summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildscripts/vcxproj.header2
-rw-r--r--jstests/core/jssymbol.js35
-rw-r--r--jstests/mmap_v1/dur_remove_old_journals.js1
-rw-r--r--src/mongo/scripting/mozjs/PosixNSPR.cpp11
-rw-r--r--src/mongo/scripting/mozjs/base.cpp26
-rw-r--r--src/mongo/scripting/mozjs/base.h21
-rw-r--r--src/mongo/scripting/mozjs/bson.cpp22
-rw-r--r--src/mongo/scripting/mozjs/bson.h14
-rw-r--r--src/mongo/scripting/mozjs/engine.cpp2
-rw-r--r--src/mongo/scripting/mozjs/implscope.cpp14
-rw-r--r--src/mongo/scripting/mozjs/internedstring.cpp2
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp40
-rw-r--r--src/mongo/scripting/mozjs/mongohelpers.cpp2
-rw-r--r--src/mongo/scripting/mozjs/numberlong.cpp6
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.cpp14
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.h6
-rw-r--r--src/mongo/scripting/mozjs/oid.cpp2
-rw-r--r--src/mongo/scripting/mozjs/valuereader.cpp3
-rw-r--r--src/mongo/scripting/mozjs/valuewriter.cpp41
-rw-r--r--src/mongo/scripting/mozjs/wraptype.h60
-rw-r--r--src/third_party/SConscript2
-rw-r--r--src/third_party/mozjs-45/SConscript136
22 files changed, 361 insertions, 101 deletions
diff --git a/buildscripts/vcxproj.header b/buildscripts/vcxproj.header
index 190c8bc1bd0..45c5de18230 100644
--- a/buildscripts/vcxproj.header
+++ b/buildscripts/vcxproj.header
@@ -100,7 +100,7 @@
<ItemDefinitionGroup>
<ClCompile>
<ObjectFileName>Build/%(RelativeDir)/</ObjectFileName>
- <AdditionalIncludeDirectories>src;src\mongo;src\third_party\mozjs-38\include;src\third_party\pcre-8.38;src\third_party\boost-1.60.0;src\third_party\snappy-1.1.3;src\third_party\s2;src\third_party\yaml-cpp-0.5.3\include;src\third_party\wiredtiger\src\include</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>src;src\mongo;src\third_party\mozjs-45\include;src\third_party\pcre-8.38;src\third_party\boost-1.60.0;src\third_party\snappy-1.1.3;src\third_party\s2;src\third_party\yaml-cpp-0.5.3\include;src\third_party\wiredtiger\src\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601;WIN32;XP_WIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- above is temp - NTDDI etc. should be configurable, not finished yet, this gets us compiling some for now.
<PreprocessorDefinitions>WIN32;XP_WIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
diff --git a/jstests/core/jssymbol.js b/jstests/core/jssymbol.js
new file mode 100644
index 00000000000..62843405c9a
--- /dev/null
+++ b/jstests/core/jssymbol.js
@@ -0,0 +1,35 @@
+// Test Symbol.toPrimitive works for DB and BSON objects
+//
+(function() {
+ // Exercise Symbol.toPrimitive on DB objects
+ // clang-format off
+ assert(`${db}` === 'test');
+ // clang-format on
+ assert(isNaN(+db));
+
+ // Exercise the special Symbol methods and make sure DB.getProperty handles them
+ assert(db[Symbol.iterator] != 1);
+ assert(db[Symbol.match] != 1);
+ assert(db[Symbol.species] != 1);
+ assert(db[Symbol.toPrimitive] != 1);
+
+ // Exercise Symbol.toPrimitive on BSON objects
+ col1 = db.jssymbol_col;
+ col1.insert({});
+ a = db.getCollection("jssymbol_col").getIndexes()[0];
+
+ assert(isNaN(+a));
+ assert(+a.v == 1);
+ // clang-format off
+ assert(`${a.v}` == 1);
+ assert(`${a}` == '[object BSON]');
+ // clang-format on
+
+ // Exercise the special Symbol methods and make sure BSON.resolve handles them
+ assert(db[Symbol.iterator] != 1);
+ assert(db[Symbol.match] != 1);
+ assert(db[Symbol.species] != 1);
+ assert(db[Symbol.toPrimitive] != 1);
+
+ col1.drop();
+})();
diff --git a/jstests/mmap_v1/dur_remove_old_journals.js b/jstests/mmap_v1/dur_remove_old_journals.js
index 8ea2d8c724c..0d1b930815b 100644
--- a/jstests/mmap_v1/dur_remove_old_journals.js
+++ b/jstests/mmap_v1/dur_remove_old_journals.js
@@ -73,6 +73,7 @@ if (db.serverBuildInfo().bits == 32) {
db.adminCommand({fsync: 1});
db.foo.remove({});
db.adminCommand({fsync: 1});
+ gc();
}
}
diff --git a/src/mongo/scripting/mozjs/PosixNSPR.cpp b/src/mongo/scripting/mozjs/PosixNSPR.cpp
index dae1779e0b3..b6c36d760d3 100644
--- a/src/mongo/scripting/mozjs/PosixNSPR.cpp
+++ b/src/mongo/scripting/mozjs/PosixNSPR.cpp
@@ -77,6 +77,15 @@ void PR_DestroyFakeThread(PRThread* thread) {
} // namespace mongo
+// In mozjs-45, js_delete takes a const pointer which is incompatible with std::unique_ptr.
+template <class T>
+static MOZ_ALWAYS_INLINE void js_delete_nonconst(T* p) {
+ if (p) {
+ p->~T();
+ js_free(p);
+ }
+}
+
PRThread* PR_CreateThread(PRThreadType type,
void (*start)(void* arg),
void* arg,
@@ -90,7 +99,7 @@ PRThread* PR_CreateThread(PRThreadType type,
try {
std::unique_ptr<nspr::Thread, void (*)(nspr::Thread*)> t(
js_new<nspr::Thread>(start, arg, state != PR_UNJOINABLE_THREAD),
- js_delete<nspr::Thread>);
+ js_delete_nonconst<nspr::Thread>);
t->thread() = mongo::stdx::thread(&nspr::Thread::ThreadRoutine, t.get());
diff --git a/src/mongo/scripting/mozjs/base.cpp b/src/mongo/scripting/mozjs/base.cpp
index b85229ae354..7bcc345dab7 100644
--- a/src/mongo/scripting/mozjs/base.cpp
+++ b/src/mongo/scripting/mozjs/base.cpp
@@ -41,15 +41,17 @@ const char* const BaseInfo::inheritFrom = nullptr;
void BaseInfo::addProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue v) {}
+ JS::HandleValue v) {}
void BaseInfo::call(JSContext* cx, JS::CallArgs args) {}
void BaseInfo::construct(JSContext* cx, JS::CallArgs args) {}
-void BaseInfo::convert(JSContext* cx,
- JS::HandleObject obj,
- JSType type,
- JS::MutableHandleValue vp) {}
-void BaseInfo::delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* succeeded) {}
-void BaseInfo::enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties) {}
+void BaseInfo::delProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::ObjectOpResult& result) {}
+void BaseInfo::enumerate(JSContext* cx,
+ JS::HandleObject obj,
+ JS::AutoIdVector& properties,
+ bool enumerableOnly) {}
void BaseInfo::finalize(JSFreeOp* fop, JSObject* obj) {}
void BaseInfo::getProperty(JSContext* cx,
JS::HandleObject obj,
@@ -59,10 +61,16 @@ void BaseInfo::hasInstance(JSContext* cx,
JS::HandleObject obj,
JS::MutableHandleValue vp,
bool* bp) {}
+bool BaseInfo::mayResolve(const JSAtomState& names, jsid id, JSObject* maybeObj) {
+ return false;
+}
void BaseInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto) {}
void BaseInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) {}
-void BaseInfo::setProperty(
- JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp) {}
+void BaseInfo::setProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::MutableHandleValue vp,
+ JS::ObjectOpResult& result) {}
} // namespace mozjs
} // namespace mongo
diff --git a/src/mongo/scripting/mozjs/base.h b/src/mongo/scripting/mozjs/base.h
index fe90ea65b97..6072b652b21 100644
--- a/src/mongo/scripting/mozjs/base.h
+++ b/src/mongo/scripting/mozjs/base.h
@@ -61,15 +61,17 @@ struct BaseInfo {
static void addProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue v);
+ JS::HandleValue v);
static void call(JSContext* cx, JS::CallArgs args);
static void construct(JSContext* cx, JS::CallArgs args);
- static void convert(JSContext* cx,
- JS::HandleObject obj,
- JSType type,
- JS::MutableHandleValue vp);
- static void delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* succeeded);
- static void enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties);
+ static void delProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::ObjectOpResult& result);
+ static void enumerate(JSContext* cx,
+ JS::HandleObject obj,
+ JS::AutoIdVector& properties,
+ bool enumerableOnly);
static void finalize(JSFreeOp* fop, JSObject* obj);
static void getProperty(JSContext* cx,
JS::HandleObject obj,
@@ -79,13 +81,14 @@ struct BaseInfo {
JS::HandleObject obj,
JS::MutableHandleValue vp,
bool* bp);
+ static bool mayResolve(const JSAtomState& names, jsid id, JSObject* maybeObj);
static void postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto);
static void resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp);
static void setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- bool strict,
- JS::MutableHandleValue vp);
+ JS::MutableHandleValue vp,
+ JS::ObjectOpResult& result);
};
} // namespace mozjs
diff --git a/src/mongo/scripting/mozjs/bson.cpp b/src/mongo/scripting/mozjs/bson.cpp
index 0cb60fb6117..cf73b44dc55 100644
--- a/src/mongo/scripting/mozjs/bson.cpp
+++ b/src/mongo/scripting/mozjs/bson.cpp
@@ -119,7 +119,10 @@ void BSONInfo::finalize(JSFreeOp* fop, JSObject* obj) {
delete holder;
}
-void BSONInfo::enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties) {
+void BSONInfo::enumerate(JSContext* cx,
+ JS::HandleObject obj,
+ JS::AutoIdVector& properties,
+ bool enumerableOnly) {
auto holder = getValidHolder(cx, obj);
if (!holder)
@@ -148,13 +151,17 @@ void BSONInfo::enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector&
}
}
-void BSONInfo::setProperty(
- JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp) {
+void BSONInfo::setProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::MutableHandleValue vp,
+ JS::ObjectOpResult& result) {
auto holder = getValidHolder(cx, obj);
if (holder) {
if (holder->_readOnly) {
uasserted(ErrorCodes::BadValue, "Read only object");
+ return;
}
auto iter = holder->_removed.find(IdWrapper(cx, id).toString());
@@ -167,14 +174,19 @@ void BSONInfo::setProperty(
}
ObjectWrapper(cx, obj).defineProperty(id, vp, JSPROP_ENUMERATE);
+ result.succeed();
}
-void BSONInfo::delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* succeeded) {
+void BSONInfo::delProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::ObjectOpResult& result) {
auto holder = getValidHolder(cx, obj);
if (holder) {
if (holder->_readOnly) {
uasserted(ErrorCodes::BadValue, "Read only object");
+ return;
}
holder->_altered = true;
@@ -183,7 +195,7 @@ void BSONInfo::delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
holder->_removed[IdWrapper(cx, id).toStringData(&jsstr)] = true;
}
- *succeeded = true;
+ result.succeed();
}
void BSONInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) {
diff --git a/src/mongo/scripting/mozjs/bson.h b/src/mongo/scripting/mozjs/bson.h
index d341f0a856b..475bda4e64e 100644
--- a/src/mongo/scripting/mozjs/bson.h
+++ b/src/mongo/scripting/mozjs/bson.h
@@ -47,15 +47,21 @@ namespace mozjs {
* ::make() from C++.
*/
struct BSONInfo : public BaseInfo {
- static void delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* succeeded);
- static void enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties);
+ static void delProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::ObjectOpResult& result);
+ static void enumerate(JSContext* cx,
+ JS::HandleObject obj,
+ JS::AutoIdVector& properties,
+ bool enumerableOnly);
static void finalize(JSFreeOp* fop, JSObject* obj);
static void resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp);
static void setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- bool strict,
- JS::MutableHandleValue vp);
+ JS::MutableHandleValue vp,
+ JS::ObjectOpResult& result);
static const char* const className;
static const unsigned classFlags = JSCLASS_HAS_PRIVATE;
diff --git a/src/mongo/scripting/mozjs/engine.cpp b/src/mongo/scripting/mozjs/engine.cpp
index 54c6c5555e6..90038dbea35 100644
--- a/src/mongo/scripting/mozjs/engine.cpp
+++ b/src/mongo/scripting/mozjs/engine.cpp
@@ -32,6 +32,8 @@
#include "mongo/scripting/mozjs/engine.h"
+#include <js/Initialization.h>
+
#include "mongo/db/operation_context.h"
#include "mongo/db/server_parameters.h"
#include "mongo/scripting/mozjs/implscope.h"
diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp
index 406ccfee1a7..527f81db279 100644
--- a/src/mongo/scripting/mozjs/implscope.cpp
+++ b/src/mongo/scripting/mozjs/implscope.cpp
@@ -34,6 +34,7 @@
#include <jscustomallocator.h>
#include <jsfriendapi.h>
+#include <js/CharacterEncoding.h>
#include "mongo/base/error_codes.h"
#include "mongo/db/operation_context.h"
@@ -242,10 +243,11 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) {
if (engine->isJITEnabled()) {
JS::RuntimeOptionsRef(_runtime)
.setAsmJS(true)
+ .setThrowOnAsmJSValidationFailure(true)
.setBaseline(true)
.setIon(true)
- .setNativeRegExp(true)
- .setUnboxedObjects(true);
+ .setAsyncStack(false)
+ .setNativeRegExp(true);
}
const StackLocator locator;
@@ -470,7 +472,7 @@ void MozJSImplScope::newFunction(StringData raw, JS::MutableHandleValue out) {
JS::CompileOptions co(_context);
setCompileOptions(&co);
- _checkErrorState(JS::Evaluate(_context, _global, co, code.c_str(), code.length(), out));
+ _checkErrorState(JS::Evaluate(_context, co, code.c_str(), code.length(), out));
}
BSONObj MozJSImplScope::callThreadArgs(const BSONObj& args) {
@@ -526,7 +528,7 @@ void MozJSImplScope::_MozJSCreateFunction(const char* raw,
JS::CompileOptions co(_context);
setCompileOptions(&co);
- _checkErrorState(JS::Evaluate(_context, _global, co, code.c_str(), code.length(), fun));
+ _checkErrorState(JS::Evaluate(_context, co, code.c_str(), code.length(), fun));
uassert(10232,
"not a function",
fun.isObject() && JS_ObjectIsFunction(_context, fun.toObjectOrNull()));
@@ -635,7 +637,7 @@ bool MozJSImplScope::exec(StringData code,
co.setFile(name.c_str());
JS::RootedScript script(_context);
- bool success = JS::Compile(_context, _global, co, code.rawData(), code.size(), &script);
+ bool success = JS::Compile(_context, co, code.rawData(), code.size(), &script);
if (_checkErrorState(success, reportError, assertOnError))
return false;
@@ -645,7 +647,7 @@ bool MozJSImplScope::exec(StringData code,
JS::RootedValue out(_context);
- success = JS_ExecuteScript(_context, _global, script, &out);
+ success = JS_ExecuteScript(_context, script, &out);
if (timeoutMs)
_engine->getDeadlineMonitor().stopDeadline(this);
diff --git a/src/mongo/scripting/mozjs/internedstring.cpp b/src/mongo/scripting/mozjs/internedstring.cpp
index 61510823f2c..8f7e9ef6673 100644
--- a/src/mongo/scripting/mozjs/internedstring.cpp
+++ b/src/mongo/scripting/mozjs/internedstring.cpp
@@ -42,7 +42,7 @@ InternedStringTable::InternedStringTable(JSContext* cx) {
#define MONGO_MOZJS_INTERNED_STRING(name, str) \
do { \
- auto s = JS_InternString(cx, str); \
+ auto s = JS_AtomizeAndPinString(cx, str); \
if (!s) { \
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_InternString"); \
} \
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index 92d73db5f9d..53bf47c77c9 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -269,29 +269,39 @@ void MongoBase::Functions::insert::call(JSContext* cx, JS::CallArgs args) {
return ValueWriter(cx, value).toBSON();
};
- if (args.get(1).isObject() && JS_IsArrayObject(cx, args.get(1))) {
- JS::RootedObject obj(cx, args.get(1).toObjectOrNull());
- ObjectWrapper array(cx, obj);
+ if (args.get(1).isObject()) {
+ bool isArray;
- std::vector<BSONObj> bos;
+ if (!JS_IsArrayObject(cx, args.get(1), &isArray)) {
+ uasserted(ErrorCodes::BadValue, "Failure to check is object an array");
+ }
- bool foundElement = false;
+ if (isArray) {
+ JS::RootedObject obj(cx, args.get(1).toObjectOrNull());
+ ObjectWrapper array(cx, obj);
- array.enumerate([&](JS::HandleId id) {
- foundElement = true;
+ std::vector<BSONObj> bos;
- JS::RootedValue value(cx);
- array.getValue(id, &value);
+ bool foundElement = false;
- bos.push_back(addId(value));
+ array.enumerate([&](JS::HandleId id) {
+ foundElement = true;
- return true;
- });
+ JS::RootedValue value(cx);
+ array.getValue(id, &value);
- if (!foundElement)
- uasserted(ErrorCodes::BadValue, "attempted to insert an empty array");
+ bos.push_back(addId(value));
- conn->insert(ns, bos, flags);
+ return true;
+ });
+
+ if (!foundElement)
+ uasserted(ErrorCodes::BadValue, "attempted to insert an empty array");
+
+ conn->insert(ns, bos, flags);
+ } else {
+ conn->insert(ns, addId(args.get(1)));
+ }
} else {
conn->insert(ns, addId(args.get(1)));
}
diff --git a/src/mongo/scripting/mozjs/mongohelpers.cpp b/src/mongo/scripting/mozjs/mongohelpers.cpp
index 5ca32e38f28..02db4115056 100644
--- a/src/mongo/scripting/mozjs/mongohelpers.cpp
+++ b/src/mongo/scripting/mozjs/mongohelpers.cpp
@@ -71,7 +71,7 @@ void MongoHelpersInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::H
// Initialize the reflection API and move it under the MongoHelpers object
uassert(ErrorCodes::JSInterpreterFailure,
"Error initializing javascript reflection API",
- JS_InitReflect(cx, global));
+ JS_InitReflectParse(cx, global));
JS::RootedValue reflectValue(cx);
globalWrapper.getValue(kReflectName, &reflectValue);
globalWrapper.deleteProperty(kReflectName);
diff --git a/src/mongo/scripting/mozjs/numberlong.cpp b/src/mongo/scripting/mozjs/numberlong.cpp
index 28d4999885d..2244c9d25b9 100644
--- a/src/mongo/scripting/mozjs/numberlong.cpp
+++ b/src/mongo/scripting/mozjs/numberlong.cpp
@@ -215,7 +215,7 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
proto,
getScope(cx)->getInternedStringId(InternedString::floatApprox),
undef,
- JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_SHARED,
+ JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::floatApprox, true, NumberLongInfo>,
nullptr)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
@@ -226,7 +226,7 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
proto,
getScope(cx)->getInternedStringId(InternedString::top),
undef,
- JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_SHARED,
+ JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::top, true, NumberLongInfo>,
nullptr)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
@@ -238,7 +238,7 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
proto,
getScope(cx)->getInternedStringId(InternedString::bottom),
undef,
- JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_SHARED,
+ JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::bottom, true, NumberLongInfo>,
nullptr)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
diff --git a/src/mongo/scripting/mozjs/objectwrapper.cpp b/src/mongo/scripting/mozjs/objectwrapper.cpp
index eb15dacccc6..6f26833573d 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.cpp
+++ b/src/mongo/scripting/mozjs/objectwrapper.cpp
@@ -537,13 +537,19 @@ ObjectWrapper::WriteFieldRecursionFrame::WriteFieldRecursionFrame(JSContext* cx,
JSObject* obj,
BSONObjBuilder* parent,
StringData sd)
- : thisv(cx, obj), ids(cx, JS_Enumerate(cx, thisv)) {
+ : thisv(cx, obj), ids(cx, JS::IdVector(cx)) {
if (parent) {
- subbob.emplace(JS_IsArrayObject(cx, thisv) ? parent->subarrayStart(sd)
- : parent->subobjStart(sd));
+ bool isArray;
+
+ if (!JS_IsArrayObject(cx, thisv, &isArray)) {
+ throwCurrentJSException(
+ cx, ErrorCodes::JSInterpreterFailure, "Failure to check object is an array");
+ }
+
+ subbob.emplace(isArray ? parent->subarrayStart(sd) : parent->subobjStart(sd));
}
- if (!ids) {
+ if (!JS_Enumerate(cx, thisv, &ids)) {
throwCurrentJSException(
cx, ErrorCodes::JSInterpreterFailure, "Failure to enumerate object");
}
diff --git a/src/mongo/scripting/mozjs/objectwrapper.h b/src/mongo/scripting/mozjs/objectwrapper.h
index 42be21ff36f..8c85a5b42d1 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.h
+++ b/src/mongo/scripting/mozjs/objectwrapper.h
@@ -147,9 +147,9 @@ public:
*/
template <typename T>
void enumerate(T&& callback) {
- JS::AutoIdArray ids(_context, JS_Enumerate(_context, _object));
+ JS::Rooted<JS::IdVector> ids(_context, JS::IdVector(_context));
- if (!ids)
+ if (!JS_Enumerate(_context, _object, &ids))
throwCurrentJSException(
_context, ErrorCodes::JSInterpreterFailure, "Failure to enumerate object");
@@ -198,7 +198,7 @@ private:
JS::RootedObject thisv;
// ids for the keys of thisv
- JS::AutoIdArray ids;
+ JS::Rooted<JS::IdVector> ids;
// Current index of the current key we're working on
std::size_t idx = 0;
diff --git a/src/mongo/scripting/mozjs/oid.cpp b/src/mongo/scripting/mozjs/oid.cpp
index e24dd3f0aca..afd6345441a 100644
--- a/src/mongo/scripting/mozjs/oid.cpp
+++ b/src/mongo/scripting/mozjs/oid.cpp
@@ -117,7 +117,7 @@ void OIDInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObje
proto,
getScope(cx)->getInternedStringId(InternedString::str),
undef,
- JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_SHARED,
+ JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::getter, true, OIDInfo>,
nullptr)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
diff --git a/src/mongo/scripting/mozjs/valuereader.cpp b/src/mongo/scripting/mozjs/valuereader.cpp
index bc1b61903ba..4383ab805a8 100644
--- a/src/mongo/scripting/mozjs/valuereader.cpp
+++ b/src/mongo/scripting/mozjs/valuereader.cpp
@@ -34,6 +34,7 @@
#include <cstdio>
#include <js/CharacterEncoding.h>
+#include <js/Date.h>
#include "mongo/base/error_codes.h"
#include "mongo/platform/decimal128.h"
@@ -117,7 +118,7 @@ void ValueReader::fromBSONElement(const BSONElement& elem, const BSONObj& parent
return;
case mongo::Date:
_value.setObjectOrNull(
- JS_NewDateObjectMsec(_context, elem.Date().toMillisSinceEpoch()));
+ JS::NewDateObject(_context, JS::TimeClip(elem.Date().toMillisSinceEpoch())));
return;
case mongo::Bool:
_value.setBoolean(elem.Bool());
diff --git a/src/mongo/scripting/mozjs/valuewriter.cpp b/src/mongo/scripting/mozjs/valuewriter.cpp
index 44465ef86d5..b4e015b1bc9 100644
--- a/src/mongo/scripting/mozjs/valuewriter.cpp
+++ b/src/mongo/scripting/mozjs/valuewriter.cpp
@@ -59,8 +59,15 @@ int ValueWriter::type() {
return Undefined;
if (_value.isString())
return String;
- if (JS_IsArrayObject(_context, _value))
+
+ bool isArray;
+
+ if (!JS_IsArrayObject(_context, _value, &isArray)) {
+ uasserted(ErrorCodes::BadValue, "unable to check if type is an array");
+ }
+ if (isArray)
return Array;
+
if (_value.isBoolean())
return Bool;
@@ -73,8 +80,14 @@ int ValueWriter::type() {
if (_value.isObject()) {
JS::RootedObject obj(_context, _value.toObjectOrNull());
- if (JS_ObjectIsDate(_context, obj))
+ bool isDate;
+
+ if (!JS_ObjectIsDate(_context, obj, &isDate)) {
+ uasserted(ErrorCodes::BadValue, "unable to check if type is a date");
+ }
+ if (isDate)
return Date;
+
if (JS_ObjectIsFunction(_context, obj))
return Code;
@@ -91,7 +104,14 @@ std::string ValueWriter::typeAsString() {
return "undefined";
if (_value.isString())
return "string";
- if (JS_IsArrayObject(_context, _value))
+
+ bool isArray;
+
+ if (!JS_IsArrayObject(_context, _value, &isArray)) {
+ uasserted(ErrorCodes::BadValue, "unable to check if type is an array");
+ }
+
+ if (isArray)
return "array";
if (_value.isBoolean())
return "boolean";
@@ -100,10 +120,21 @@ std::string ValueWriter::typeAsString() {
if (_value.isObject()) {
JS::RootedObject obj(_context, _value.toObjectOrNull());
- if (JS_IsArrayObject(_context, obj))
+
+ if (!JS_IsArrayObject(_context, obj, &isArray)) {
+ uasserted(ErrorCodes::BadValue, "unable to check if type is an array");
+ }
+ if (isArray)
return "array";
- if (JS_ObjectIsDate(_context, obj))
+
+ bool isDate;
+
+ if (!JS_ObjectIsDate(_context, obj, &isDate)) {
+ uasserted(ErrorCodes::BadValue, "unable to check if type is a date");
+ }
+ if (isDate)
return "date";
+
if (JS_ObjectIsFunction(_context, obj))
return "function";
diff --git a/src/mongo/scripting/mozjs/wraptype.h b/src/mongo/scripting/mozjs/wraptype.h
index 3729e964c0e..d6fb135da44 100644
--- a/src/mongo/scripting/mozjs/wraptype.h
+++ b/src/mongo/scripting/mozjs/wraptype.h
@@ -101,7 +101,7 @@ bool wrapFunction(JSContext* cx, unsigned argc, JS::Value* vp) {
// Now all the spidermonkey type methods
template <typename T>
-bool addProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue v) {
+bool addProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v) {
try {
T::addProperty(cx, obj, id, v);
return true;
@@ -134,9 +134,9 @@ bool construct(JSContext* cx, unsigned argc, JS::Value* vp) {
};
template <typename T>
-bool convert(JSContext* cx, JS::HandleObject obj, JSType type, JS::MutableHandleValue vp) {
+bool delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::ObjectOpResult& result) {
try {
- T::convert(cx, obj, type, vp);
+ T::delProperty(cx, obj, id, result);
return true;
} catch (...) {
mongoToJSException(cx);
@@ -145,9 +145,12 @@ bool convert(JSContext* cx, JS::HandleObject obj, JSType type, JS::MutableHandle
};
template <typename T>
-bool delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* succeeded) {
+bool enumerate(JSContext* cx,
+ JS::HandleObject obj,
+ JS::AutoIdVector& properties,
+ bool enumerableOnly) {
try {
- T::delProperty(cx, obj, id, succeeded);
+ T::enumerate(cx, obj, properties, enumerableOnly);
return true;
} catch (...) {
mongoToJSException(cx);
@@ -156,18 +159,13 @@ bool delProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* suc
};
template <typename T>
-bool enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties) {
- try {
- T::enumerate(cx, obj, properties);
+bool getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) {
+ if (JSID_IS_SYMBOL(id)) {
+ // Just default to the SpiderMonkey's standard implementations for Symbol methods
+ vp.setUndefined();
return true;
- } catch (...) {
- mongoToJSException(cx);
- return false;
}
-};
-template <typename T>
-bool getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) {
try {
T::getProperty(cx, obj, id, vp);
return true;
@@ -189,10 +187,13 @@ bool hasInstance(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp,
};
template <typename T>
-bool setProperty(
- JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp) {
+bool setProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ JS::MutableHandleValue vp,
+ JS::ObjectOpResult& result) {
try {
- T::setProperty(cx, obj, id, strict, vp);
+ T::setProperty(cx, obj, id, vp, result);
return true;
} catch (...) {
mongoToJSException(cx);
@@ -202,6 +203,12 @@ bool setProperty(
template <typename T>
bool resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) {
+ if (JSID_IS_SYMBOL(id)) {
+ // Just default to the SpiderMonkey's standard implementations for Symbol methods
+ *resolvedp = false;
+ return true;
+ }
+
try {
T::resolve(cx, obj, id, resolvedp);
return true;
@@ -228,7 +235,7 @@ public:
// We don't use the regular enumerate because we want the fancy new one
nullptr,
T::resolve != BaseInfo::resolve ? smUtils::resolve<T> : nullptr,
- T::convert != BaseInfo::convert ? smUtils::convert<T> : nullptr,
+ T::mayResolve != BaseInfo::mayResolve ? T::mayResolve : nullptr,
T::finalize != BaseInfo::finalize ? T::finalize : nullptr,
T::call != BaseInfo::call ? smUtils::call<T> : nullptr,
T::hasInstance != BaseInfo::hasInstance ? smUtils::hasInstance<T> : nullptr,
@@ -279,15 +286,7 @@ public:
* types without a constructor or inside the constructor
*/
void newObject(JS::MutableHandleObject out) {
- // The regular form of JS_NewObject, where we pass proto as the
- // third param, actually does a global object lookup for some
- // reason. This way allows object creation with non-public
- // prototypes and if someone deletes the symbol up the chain.
- out.set(_assertPtr(JS_NewObject(_context, &_jsclass, JS::NullPtr())));
-
- if (!JS_SetPrototype(_context, out, _proto))
- throwCurrentJSException(
- _context, ErrorCodes::JSInterpreterFailure, "Failed to set prototype");
+ out.set(_assertPtr(JS_NewObjectWithGivenProto(_context, &_jsclass, _proto)));
}
void newObject(JS::MutableHandleValue out) {
@@ -385,7 +384,7 @@ private:
// See newObject() for why we have to do this dance with the explicit
// SetPrototype
- _proto.init(_context, _assertPtr(JS_NewObject(_context, &_jsclass, JS::NullPtr())));
+ _proto.init(_context, _assertPtr(JS_NewObject(_context, &_jsclass)));
if (parent.get() && !JS_SetPrototype(_context, _proto, parent))
throwCurrentJSException(
_context, ErrorCodes::JSInterpreterFailure, "Failed to set prototype");
@@ -404,7 +403,6 @@ private:
dassert(T::addProperty == BaseInfo::addProperty);
dassert(T::call == BaseInfo::call);
dassert(T::construct == BaseInfo::construct);
- dassert(T::convert == BaseInfo::convert);
dassert(T::delProperty == BaseInfo::delProperty);
dassert(T::enumerate == BaseInfo::enumerate);
dassert(T::finalize == BaseInfo::finalize);
@@ -445,7 +443,7 @@ private:
// ensure that these two structures are equal.
//
// This is a landmine to watch out for during upgrades
- using enumerateT = bool (*)(JSContext*, JS::HandleObject, JS::AutoIdVector&);
+ using enumerateT = bool (*)(JSContext*, JS::HandleObject, JS::AutoIdVector&, bool);
void _installEnumerate(enumerateT enumerate) {
if (!enumerate)
return;
@@ -486,7 +484,7 @@ private:
if (!ctor)
return;
- auto ptr = JS_NewFunction(_context, ctor, 0, JSFUN_CONSTRUCTOR, JS::NullPtr(), nullptr);
+ auto ptr = JS_NewFunction(_context, ctor, 0, JSFUN_CONSTRUCTOR, nullptr);
if (!ptr) {
throwCurrentJSException(
_context, ErrorCodes::JSInterpreterFailure, "Failed to install constructor");
diff --git a/src/third_party/SConscript b/src/third_party/SConscript
index 616be6d7ff3..5ef4a01fa2b 100644
--- a/src/third_party/SConscript
+++ b/src/third_party/SConscript
@@ -8,7 +8,7 @@ boostSuffix = "-1.60.0"
snappySuffix = '-1.1.3'
zlibSuffix = '-1.2.8'
pcreSuffix = "-8.38"
-mozjsSuffix = '-38'
+mozjsSuffix = '-45'
yamlSuffix = '-0.5.3'
icuSuffix = '-57.1'
gperftoolsSuffix = '-2.5'
diff --git a/src/third_party/mozjs-45/SConscript b/src/third_party/mozjs-45/SConscript
new file mode 100644
index 00000000000..4d1efd7a58b
--- /dev/null
+++ b/src/third_party/mozjs-45/SConscript
@@ -0,0 +1,136 @@
+# -*- mode: python -*-
+
+Import([
+ "get_option",
+ "env",
+ ])
+
+env = env.Clone()
+env.InjectThirdPartyIncludePaths(libraries=['zlib'])
+
+def removeIfPresent(lst, item):
+ try:
+ lst.remove(item)
+ except ValueError:
+ pass
+
+for to_remove in ['-Werror', '-Wall', '-W']:
+ removeIfPresent(env['CCFLAGS'], to_remove)
+
+# See what -D's show up in make. The AB_CD one might change, but we're little
+# endian only for now so I think it's sane
+env.Prepend(CPPDEFINES=[
+ 'IMPL_MFBT',
+ 'JS_USE_CUSTOM_ALLOCATOR',
+ 'STATIC_JS_API=1',
+ 'U_NO_DEFAULT_INCLUDE_UTF_HEADERS=1',
+ ])
+
+if get_option('spider-monkey-dbg') == "on":
+ env.Prepend(CPPDEFINES=[
+ 'DEBUG',
+ 'JS_DEBUG',
+ 'JS_GC_ZEAL',
+ ])
+
+# js-confdefs.h has to get in front on windows or wherever
+if env.TargetOSIs('windows'):
+ env.Prepend(CCFLAGS=[
+ '/FI', 'js-confdefs.h',
+
+ # 'declaration' : no matching operator delete found; memory will not be freed if
+ # initialization throws an exception
+ '/wd4291',
+
+ # name" : the inline specifier cannot be used when a friend declaration refers to a
+ # specialization of a function template
+ '/wd4396',
+
+ # nonstandard extension used : zero-sized array in struct/union
+ '/wd4200',
+
+ # 'identifier' : no suitable definition provided for explicit template instantiation
+ # request
+ '/wd4661',
+
+ # 'operation' : unsafe mix of type 'type' and type 'type' in operation
+ '/wd4805',
+ ])
+else:
+ if env.TargetOSIs('solaris'):
+ env.Prepend(CCFLAGS=[
+ '-include', 'solaris_hacks.h'
+ ])
+
+ env.Append(
+ CCFLAGS=[
+ '-include', 'js-confdefs.h',
+ '-Wno-invalid-offsetof',
+ ],
+ CXXFLAGS=[
+ '-Wno-non-virtual-dtor',
+ ],
+ )
+
+# js/src, js/public and mfbt are the only required sources right now, that
+# could change in the future
+#
+# Also:
+# We pre-generate configs for platforms and just check them in. Running
+# mozilla's config requires a relatively huge portion of their tree.
+env.Prepend(CPPPATH=[
+ '#src',
+ '$BUILD_DIR',
+ 'extract/js/src',
+ 'extract/mfbt',
+ 'extract/intl/icu/source/common',
+ 'include',
+ 'mongo_sources',
+ 'platform/' + env["TARGET_ARCH"] + "/" + env["TARGET_OS"] + "/build",
+ 'platform/' + env["TARGET_ARCH"] + "/" + env["TARGET_OS"] + "/include",
+])
+
+sources = [
+ "extract/js/src/builtin/RegExp.cpp",
+ "extract/js/src/frontend/Parser.cpp",
+ "extract/js/src/jsarray.cpp",
+ "extract/js/src/jsatom.cpp",
+ "extract/js/src/jsmath.cpp",
+ "extract/js/src/jsutil.cpp",
+ "extract/js/src/gc/StoreBuffer.cpp",
+ "extract/js/src/mfbt/Unified_cpp_mfbt0.cpp",
+ "extract/js/src/perf/pm_stub.cpp",
+ "extract/js/src/vm/Initialization.cpp",
+ "extract/mfbt/Compression.cpp",
+]
+
+
+if env['TARGET_ARCH'] == 'x86_64' and not env.TargetOSIs('solaris'):
+ sources.extend([
+ "extract/js/src/jit/x86-shared/Disassembler-x86-shared.cpp",
+ ])
+
+if env.TargetOSIs('windows'):
+ env.Prepend(CPPDEFINES=[
+ ("_CRT_RAND_S", "1")
+ ])
+ sources.extend([
+ "extract/js/src/jit/ExecutableAllocatorWin.cpp",
+ ])
+else:
+ sources.extend([
+ "extract/js/src/jit/ExecutableAllocatorPosix.cpp",
+ ])
+
+sources.extend(Glob('platform/' + env["TARGET_ARCH"] + "/" + env["TARGET_OS"] + "/build/*.cpp")),
+
+# All of those unified sources come in from configure. The files don't
+# actually build individually anymore.
+env.Library(
+ target="mozjs",
+ source=sources,
+ LIBDEPS_TAGS=[
+ # Depends on allocation symbols defined elsewhere
+ 'incomplete'
+ ],
+)