summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorGabriel Russell <gabriel.russell@mongodb.com>2019-01-30 16:35:10 +0000
committerGabriel Russell <gabriel.russell@mongodb.com>2019-01-30 19:06:17 +0000
commitd80755651cbd268c7db03ebba914051428fedeb4 (patch)
treeedeef955820a96d615876729dfa6e03ff021ea16 /src/mongo
parent6dc4072453b4ba17fed636f049c10cf1316357bb (diff)
downloadmongo-d80755651cbd268c7db03ebba914051428fedeb4.tar.gz
SERVER-29286 import and use mozjs-60
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/scripting/mozjs/PosixNSPR.cpp28
-rw-r--r--src/mongo/scripting/mozjs/base.cpp6
-rw-r--r--src/mongo/scripting/mozjs/base.h6
-rw-r--r--src/mongo/scripting/mozjs/bindata.cpp2
-rw-r--r--src/mongo/scripting/mozjs/bindata.h2
-rw-r--r--src/mongo/scripting/mozjs/bson.cpp11
-rw-r--r--src/mongo/scripting/mozjs/bson.h5
-rw-r--r--src/mongo/scripting/mozjs/cursor.cpp2
-rw-r--r--src/mongo/scripting/mozjs/cursor.h2
-rw-r--r--src/mongo/scripting/mozjs/cursor_handle.cpp2
-rw-r--r--src/mongo/scripting/mozjs/cursor_handle.h2
-rw-r--r--src/mongo/scripting/mozjs/dbref.cpp7
-rw-r--r--src/mongo/scripting/mozjs/dbref.h5
-rw-r--r--src/mongo/scripting/mozjs/exception.cpp4
-rw-r--r--src/mongo/scripting/mozjs/implscope.cpp134
-rw-r--r--src/mongo/scripting/mozjs/implscope.h11
-rw-r--r--src/mongo/scripting/mozjs/jscustomallocator.cpp14
-rw-r--r--src/mongo/scripting/mozjs/jsthread.cpp2
-rw-r--r--src/mongo/scripting/mozjs/jsthread.h2
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp2
-rw-r--r--src/mongo/scripting/mozjs/mongo.h2
-rw-r--r--src/mongo/scripting/mozjs/nativefunction.cpp2
-rw-r--r--src/mongo/scripting/mozjs/nativefunction.h2
-rw-r--r--src/mongo/scripting/mozjs/numberdecimal.cpp2
-rw-r--r--src/mongo/scripting/mozjs/numberdecimal.h2
-rw-r--r--src/mongo/scripting/mozjs/numberint.cpp2
-rw-r--r--src/mongo/scripting/mozjs/numberint.h2
-rw-r--r--src/mongo/scripting/mozjs/numberlong.cpp17
-rw-r--r--src/mongo/scripting/mozjs/numberlong.h2
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.cpp51
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.h16
-rw-r--r--src/mongo/scripting/mozjs/oid.cpp7
-rw-r--r--src/mongo/scripting/mozjs/oid.h2
-rw-r--r--src/mongo/scripting/mozjs/session.cpp2
-rw-r--r--src/mongo/scripting/mozjs/session.h2
-rw-r--r--src/mongo/scripting/mozjs/status.cpp26
-rw-r--r--src/mongo/scripting/mozjs/status.h2
-rw-r--r--src/mongo/scripting/mozjs/wraptype.h101
-rw-r--r--src/mongo/shell/error_codes.tpl.js2
-rw-r--r--src/mongo/shell/mongo.js103
-rw-r--r--src/mongo/shell/replsettest.js11
41 files changed, 310 insertions, 297 deletions
diff --git a/src/mongo/scripting/mozjs/PosixNSPR.cpp b/src/mongo/scripting/mozjs/PosixNSPR.cpp
index 63177fa9735..55a821450e6 100644
--- a/src/mongo/scripting/mozjs/PosixNSPR.cpp
+++ b/src/mongo/scripting/mozjs/PosixNSPR.cpp
@@ -289,3 +289,31 @@ PRStatus PR_WaitCondVar(PRCondVar* cvar, uint32_t timeout) {
}
}
}
+
+int32_t PR_FileDesc2NativeHandle(PRFileDesc* fd) {
+ MOZ_CRASH("PR_FileDesc2NativeHandle");
+}
+
+PRStatus PR_GetOpenFileInfo(PRFileDesc* fd, PRFileInfo* info) {
+ MOZ_CRASH("PR_GetOpenFileInfo");
+}
+
+int32_t PR_Seek(PRFileDesc* fd, int32_t offset, PRSeekWhence whence) {
+ MOZ_CRASH("PR_Seek");
+}
+
+PRFileMap* PR_CreateFileMap(PRFileDesc* fd, int64_t size, PRFileMapProtect prot) {
+ MOZ_CRASH("PR_CreateFileMap");
+}
+
+void* PR_MemMap(PRFileMap* fmap, int64_t offset, uint32_t len) {
+ MOZ_CRASH("PR_MemMap");
+}
+
+PRStatus PR_MemUnmap(void* addr, uint32_t len) {
+ MOZ_CRASH("PR_MemUnmap");
+}
+
+PRStatus PR_CloseFileMap(PRFileMap* fmap) {
+ MOZ_CRASH("PR_CloseFileMap");
+}
diff --git a/src/mongo/scripting/mozjs/base.cpp b/src/mongo/scripting/mozjs/base.cpp
index c7496dc073e..b36edd7375f 100644
--- a/src/mongo/scripting/mozjs/base.cpp
+++ b/src/mongo/scripting/mozjs/base.cpp
@@ -54,10 +54,11 @@ void BaseInfo::enumerate(JSContext* cx,
JS::HandleObject obj,
JS::AutoIdVector& properties,
bool enumerableOnly) {}
-void BaseInfo::finalize(JSFreeOp* fop, JSObject* obj) {}
+void BaseInfo::finalize(js::FreeOp* fop, JSObject* obj) {}
void BaseInfo::getProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
+ JS::HandleValue receiver,
JS::MutableHandleValue vp) {}
void BaseInfo::hasInstance(JSContext* cx,
JS::HandleObject obj,
@@ -71,7 +72,8 @@ void BaseInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, boo
void BaseInfo::setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue vp,
+ JS::HandleValue v,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result) {}
} // namespace mozjs
diff --git a/src/mongo/scripting/mozjs/base.h b/src/mongo/scripting/mozjs/base.h
index 8ed28449f01..ee60999b1c3 100644
--- a/src/mongo/scripting/mozjs/base.h
+++ b/src/mongo/scripting/mozjs/base.h
@@ -74,10 +74,11 @@ struct BaseInfo {
JS::HandleObject obj,
JS::AutoIdVector& properties,
bool enumerableOnly);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
static void getProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
+ JS::HandleValue receiver,
JS::MutableHandleValue vp);
static void hasInstance(JSContext* cx,
JS::HandleObject obj,
@@ -89,7 +90,8 @@ struct BaseInfo {
static void setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue vp,
+ JS::HandleValue v,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result);
};
diff --git a/src/mongo/scripting/mozjs/bindata.cpp b/src/mongo/scripting/mozjs/bindata.cpp
index ddf5df2ba1d..91d81182204 100644
--- a/src/mongo/scripting/mozjs/bindata.cpp
+++ b/src/mongo/scripting/mozjs/bindata.cpp
@@ -109,7 +109,7 @@ std::string* getEncoded(JSObject* thisv) {
} // namespace
-void BinDataInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void BinDataInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto str = getEncoded(obj);
if (str) {
diff --git a/src/mongo/scripting/mozjs/bindata.h b/src/mongo/scripting/mozjs/bindata.h
index 58ec68d4ad5..446c81f8107 100644
--- a/src/mongo/scripting/mozjs/bindata.h
+++ b/src/mongo/scripting/mozjs/bindata.h
@@ -42,7 +42,7 @@ namespace mozjs {
*/
struct BinDataInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(base64);
diff --git a/src/mongo/scripting/mozjs/bson.cpp b/src/mongo/scripting/mozjs/bson.cpp
index 7ce68bf1a77..e3a24a94e23 100644
--- a/src/mongo/scripting/mozjs/bson.cpp
+++ b/src/mongo/scripting/mozjs/bson.cpp
@@ -126,7 +126,7 @@ void BSONInfo::make(
JS_SetPrivate(obj, scope->trackedNew<BSONHolder>(bson, parent, scope, ro));
}
-void BSONInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void BSONInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto holder = static_cast<BSONHolder*>(JS_GetPrivate(obj));
if (!holder)
@@ -163,21 +163,24 @@ void BSONInfo::enumerate(JSContext* cx,
if (!JS_ValueToId(cx, val, &id))
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to invoke JS_ValueToId");
- properties.append(id);
+ if (!properties.append(id))
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to append property");
}
}
void BSONInfo::setProperty(JSContext* cx,
+
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue vp,
+ JS::HandleValue vp,
+ JS::HandleValue receiver,
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());
diff --git a/src/mongo/scripting/mozjs/bson.h b/src/mongo/scripting/mozjs/bson.h
index a6c55408790..565f5b0d7a8 100644
--- a/src/mongo/scripting/mozjs/bson.h
+++ b/src/mongo/scripting/mozjs/bson.h
@@ -57,12 +57,13 @@ struct BSONInfo : public BaseInfo {
JS::HandleObject obj,
JS::AutoIdVector& properties,
bool enumerableOnly);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* 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,
- JS::MutableHandleValue vp,
+ JS::HandleValue v,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result);
static const char* const className;
diff --git a/src/mongo/scripting/mozjs/cursor.cpp b/src/mongo/scripting/mozjs/cursor.cpp
index 11cc9912f7c..2b9b7da0549 100644
--- a/src/mongo/scripting/mozjs/cursor.cpp
+++ b/src/mongo/scripting/mozjs/cursor.cpp
@@ -66,7 +66,7 @@ DBClientCursor* getCursor(JS::CallArgs& args) {
} // namespace
-void CursorInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void CursorInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto cursor = static_cast<CursorInfo::CursorHolder*>(JS_GetPrivate(obj));
if (cursor) {
diff --git a/src/mongo/scripting/mozjs/cursor.h b/src/mongo/scripting/mozjs/cursor.h
index db56bd9d184..5a16563ff15 100644
--- a/src/mongo/scripting/mozjs/cursor.h
+++ b/src/mongo/scripting/mozjs/cursor.h
@@ -43,7 +43,7 @@ namespace mozjs {
* from C++. Current callers are all via the Mongo object.
*/
struct CursorInfo : public BaseInfo {
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(close);
diff --git a/src/mongo/scripting/mozjs/cursor_handle.cpp b/src/mongo/scripting/mozjs/cursor_handle.cpp
index 4ce16e32c67..fc2eda5d4e5 100644
--- a/src/mongo/scripting/mozjs/cursor_handle.cpp
+++ b/src/mongo/scripting/mozjs/cursor_handle.cpp
@@ -65,7 +65,7 @@ long long* getCursorId(JS::CallArgs& args) {
} // namespace
-void CursorHandleInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void CursorHandleInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto cursorTracker = static_cast<CursorHandleInfo::CursorTracker*>(JS_GetPrivate(obj));
if (cursorTracker) {
const long long cursorId = cursorTracker->cursorId;
diff --git a/src/mongo/scripting/mozjs/cursor_handle.h b/src/mongo/scripting/mozjs/cursor_handle.h
index 8d3641c061a..1f0f27fb299 100644
--- a/src/mongo/scripting/mozjs/cursor_handle.h
+++ b/src/mongo/scripting/mozjs/cursor_handle.h
@@ -43,7 +43,7 @@ namespace mozjs {
* callers are all via the Mongo object.
*/
struct CursorHandleInfo : public BaseInfo {
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(zeroCursorId);
diff --git a/src/mongo/scripting/mozjs/dbref.cpp b/src/mongo/scripting/mozjs/dbref.cpp
index 77cf56aed23..5340b69b097 100644
--- a/src/mongo/scripting/mozjs/dbref.cpp
+++ b/src/mongo/scripting/mozjs/dbref.cpp
@@ -69,7 +69,7 @@ void DBRefInfo::construct(JSContext* cx, JS::CallArgs args) {
args.rval().setObjectOrNull(out);
}
-void DBRefInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void DBRefInfo::finalize(js::FreeOp* fop, JSObject* obj) {
BSONInfo::finalize(fop, obj);
}
@@ -83,9 +83,10 @@ void DBRefInfo::enumerate(JSContext* cx,
void DBRefInfo::setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue vp,
+ JS::HandleValue vp,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result) {
- BSONInfo::setProperty(cx, obj, id, vp, result);
+ BSONInfo::setProperty(cx, obj, id, vp, receiver, result);
}
void DBRefInfo::delProperty(JSContext* cx,
diff --git a/src/mongo/scripting/mozjs/dbref.h b/src/mongo/scripting/mozjs/dbref.h
index 0e847dd3296..cab66b18d4c 100644
--- a/src/mongo/scripting/mozjs/dbref.h
+++ b/src/mongo/scripting/mozjs/dbref.h
@@ -59,12 +59,13 @@ struct DBRefInfo : public BaseInfo {
JS::HandleObject obj,
JS::AutoIdVector& properties,
bool enumerableOnly);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* 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,
- JS::MutableHandleValue vp,
+ JS::HandleValue vp,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result);
static void make(
diff --git a/src/mongo/scripting/mozjs/exception.cpp b/src/mongo/scripting/mozjs/exception.cpp
index 35e4155e257..56e5544d58e 100644
--- a/src/mongo/scripting/mozjs/exception.cpp
+++ b/src/mongo/scripting/mozjs/exception.cpp
@@ -35,9 +35,11 @@
#include <jsfriendapi.h>
#include <limits>
+
#include "mongo/base/static_assert.h"
#include "mongo/scripting/mozjs/implscope.h"
#include "mongo/scripting/mozjs/jsstringwrapper.h"
+#include "mongo/scripting/mozjs/mongoErrorReportToString.h"
#include "mongo/scripting/mozjs/objectwrapper.h"
#include "mongo/scripting/mozjs/valuewriter.h"
#include "mongo/util/assert_util.h"
@@ -82,7 +84,7 @@ Status JSErrorReportToStatus(JSContext* cx,
JSErrorReport* report,
ErrorCodes::Error altCode,
StringData altReason) {
- JSStringWrapper jsstr(cx, js::ErrorReportToString(cx, report));
+ JSStringWrapper jsstr(cx, mongoErrorReportToString(cx, report));
if (!jsstr)
return Status(altCode, altReason.rawData());
diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp
index 830d2df320a..9f201cc3dc7 100644
--- a/src/mongo/scripting/mozjs/implscope.cpp
+++ b/src/mongo/scripting/mozjs/implscope.cpp
@@ -121,63 +121,6 @@ struct MozJSImplScope::MozJSEntry {
MozJSImplScope* _scope;
};
-void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorReport* report) {
- auto scope = getScope(cx);
-
- // If we are recursively calling _reportError because of ReportOverRecursed, lets just quit now
- if (scope->_inReportError) {
- return;
- }
-
- scope->_inReportError = true;
- const auto guard = makeGuard([&] { scope->_inReportError = false; });
-
- if (!JSREPORT_IS_WARNING(report->flags)) {
-
- std::string exceptionMsg;
-
- try {
- // TODO: something far more elaborate that mimics the stack printing from v8
- JS::RootedValue excn(cx);
- if (JS_GetPendingException(cx, &excn) && excn.isObject()) {
- JS::RootedValue stack(cx);
-
- JS::RootedObject obj(cx, excn.toObjectOrNull());
- ObjectWrapper o(cx, obj);
- o.getValue("stack", &stack);
-
- auto stackStr = ValueWriter(cx, stack).toString();
-
- if (stackStr.empty()) {
- // The JavaScript Error objects resulting from C++ exceptions may not always
- // have a non-empty "stack" property. We instead use the line and column
- // numbers of where in the JavaScript code the C++ function was called from.
- str::stream ss;
- ss << "@" << report->filename << ":" << report->lineno << ":" << report->column
- << "\n";
- stackStr = ss;
- }
-
- auto status =
- jsExceptionToStatus(cx, excn, ErrorCodes::JSInterpreterFailure, message)
- .withReason(message);
- scope->_status = {JSExceptionInfo(std::move(stackStr), std::move(status)), message};
-
- return;
- }
-
- exceptionMsg = message;
- } catch (const DBException& dbe) {
- exceptionMsg = "Unknown error occured while processing exception";
- log() << exceptionMsg << ":" << dbe.toString() << ":" << message;
- }
-
- scope->_status =
- JSErrorReportToStatus(cx, report, ErrorCodes::JSInterpreterFailure, message)
- .withReason(exceptionMsg);
- }
-}
-
std::string MozJSImplScope::getError() {
return "";
}
@@ -219,11 +162,11 @@ void MozJSImplScope::kill() {
}
}
_sleepCondition.notify_all();
- JS_RequestInterruptCallback(_runtime);
+ JS_RequestInterruptCallback(_context);
}
void MozJSImplScope::interrupt() {
- JS_RequestInterruptCallback(_runtime);
+ JS_RequestInterruptCallback(_context);
}
bool MozJSImplScope::isKillPending() const {
@@ -242,12 +185,12 @@ bool MozJSImplScope::isJavaScriptProtectionEnabled() const {
bool MozJSImplScope::_interruptCallback(JSContext* cx) {
auto scope = getScope(cx);
- JS_SetInterruptCallback(scope->_runtime, nullptr);
- auto guard = makeGuard([&]() { JS_SetInterruptCallback(scope->_runtime, _interruptCallback); });
+ JS_DisableInterruptCallback(scope->_context);
+ auto guard = makeGuard([&]() { JS_ResetInterruptCallback(scope->_context, false); });
if (scope->_pendingGC.load() || closeToMaxMemory()) {
scope->_pendingGC.store(false);
- JS_GC(scope->_runtime);
+ JS_GC(scope->_context);
} else {
JS_MaybeGC(cx);
}
@@ -273,7 +216,7 @@ bool MozJSImplScope::_interruptCallback(JSContext* cx) {
return scope->_status.isOK();
}
-void MozJSImplScope::_gcCallback(JSRuntime* rt, JSGCStatus status, void* data) {
+void MozJSImplScope::_gcCallback(JSContext* rt, JSGCStatus status, void* data) {
if (!shouldLog(logger::LogSeverity::Debug(1))) {
// don't collect stats unless verbose
return;
@@ -360,13 +303,14 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) {
gFirstRuntimeCreated = true;
}
- _runtime = std::unique_ptr<JSRuntime, std::function<void(JSRuntime*)>>(
- JS_NewRuntime(kMaxBytesBeforeGC), [](JSRuntime* ptr) { JS_DestroyRuntime(ptr); });
- uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSRuntime", _runtime);
+ _context = std::unique_ptr<JSContext, std::function<void(JSContext*)>>(
+ JS_NewContext(kMaxBytesBeforeGC, JS::DefaultNurseryBytes),
+ [](JSContext* ptr) { JS_DestroyContext(ptr); });
+ uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSContext", _context);
// We turn on a variety of optimizations if the jit is enabled
if (engine->isJITEnabled()) {
- JS::RuntimeOptionsRef(_runtime.get())
+ JS::ContextOptionsRef(_context.get())
.setAsmJS(true)
.setThrowOnAsmJSValidationFailure(true)
.setBaseline(true)
@@ -374,7 +318,7 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) {
.setAsyncStack(false)
.setNativeRegExp(true);
} else {
- JS::RuntimeOptionsRef(_runtime.get())
+ JS::ContextOptionsRef(_context.get())
.setAsmJS(false)
.setThrowOnAsmJSValidationFailure(false)
.setBaseline(false)
@@ -383,6 +327,14 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) {
.setNativeRegExp(false);
}
+ uassert(ErrorCodes::JSInterpreterFailure,
+ "InitSelfHostedCode",
+ JS::InitSelfHostedCode(_context.get()));
+
+ uassert(ErrorCodes::ExceededMemoryLimit,
+ "Out of memory while trying to initialize javascript scope",
+ mallocMemoryLimit == 0 || mongo::sm::get_total_bytes() < mallocMemoryLimit);
+
const StackLocator locator;
const auto available = locator.available();
if (available) {
@@ -412,26 +364,19 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) {
const decltype(available_stack_space) reserve_stack_space = 64 * 1024;
#endif
- JS_SetNativeStackQuota(_runtime.get(), available_stack_space - reserve_stack_space);
+ JS_SetNativeStackQuota(_context.get(), available_stack_space - reserve_stack_space);
}
// The memory limit is in megabytes
- JS_SetGCParametersBasedOnAvailableMemory(_runtime.get(), engine->getJSHeapLimitMB());
+ JS_SetGCParametersBasedOnAvailableMemory(_context.get(), engine->getJSHeapLimitMB());
+ // TODO SERVER-39152 apply the mozilla patch to stop overriding JSGC_MAX_BYTES
+ JS_SetGCParameter(_context.get(), JSGC_MAX_BYTES, 0xffffffff);
}
-
- _context = std::unique_ptr<JSContext, std::function<void(JSContext*)>>(
- JS_NewContext(_runtime.get(), kStackChunkSize),
- [](JSContext* ptr) { JS_DestroyContext(ptr); });
- uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSContext", _context);
- uassert(ErrorCodes::ExceededMemoryLimit,
- "Out of memory while trying to initialize javascript scope",
- mallocMemoryLimit == 0 || mongo::sm::get_total_bytes() < mallocMemoryLimit);
}
MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine)
: _engine(engine),
_mr(engine),
- _runtime(_mr._runtime.get()),
_context(_mr._context.get()),
_globalProto(_context),
_global(_globalProto.getProto()),
@@ -481,16 +426,13 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine)
// The default is quite low and doesn't seem to directly correlate with
// malloc'd bytes. Set it to MAX_INT here and catching things in the
// jscustomallocator.cpp
- JS_SetGCParameter(_runtime, JSGC_MAX_BYTES, 0xffffffff);
+ JS_SetGCParameter(_context, JSGC_MAX_BYTES, 0xffffffff);
- JS_SetInterruptCallback(_runtime, _interruptCallback);
- JS_SetGCCallback(_runtime, _gcCallback, this);
+ JS_AddInterruptCallback(_context, _interruptCallback);
+ JS_SetGCCallback(_context, _gcCallback, this);
JS_SetContextPrivate(_context, this);
- JS_SetRuntimePrivate(_runtime, this);
JSAutoRequest ar(_context);
- JS_SetErrorReporter(_runtime, _reportError);
-
JSAutoCompartment ac(_context, _global);
_checkErrorState(JS_InitStandardClasses(_context, _global));
@@ -665,7 +607,8 @@ BSONObj MozJSImplScope::callThreadArgs(const BSONObj& args) {
for (int i = 0; i < argc; ++i) {
ValueReader(_context, &value).fromBSONElement(*it, args, true);
- argv.append(value);
+ if (!argv.append(value))
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to append property");
it.next();
}
@@ -732,7 +675,8 @@ int MozJSImplScope::invoke(ScriptingFunction func,
JS::RootedValue value(_context);
ValueReader(_context, &value).fromBSONElement(next, *argsObject, readOnlyArgs);
- args.append(value);
+ if (!args.append(value))
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to append property");
}
}
@@ -831,7 +775,7 @@ void MozJSImplScope::injectNative(const char* field, NativeFunction func, void*
void MozJSImplScope::gc() {
_pendingGC.store(true);
- JS_RequestInterruptCallback(_runtime);
+ JS_RequestInterruptCallback(_context);
}
void MozJSImplScope::sleep(Milliseconds ms) {
@@ -928,9 +872,10 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser
if (_status.isOK()) {
JS::RootedValue excn(_context);
if (JS_GetPendingException(_context, &excn) && excn.isObject()) {
- str::stream ss;
+ auto ss = ValueWriter(_context, excn).toString();
auto stackStr = ObjectWrapper(_context, excn).getString(InternedString::stack);
+ auto status = jsExceptionToStatus(_context, excn, ErrorCodes::JSInterpreterFailure, ss);
auto fnameStr = ObjectWrapper(_context, excn).getString(InternedString::fileName);
auto lineNum = ObjectWrapper(_context, excn).getNumberInt(InternedString::lineNumber);
auto colNum = ObjectWrapper(_context, excn).getNumberInt(InternedString::columnNumber);
@@ -944,17 +889,12 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser
stackStr = ss;
}
- if (fnameStr != "") {
- ss << "[" << fnameStr << ":" << lineNum << ":" << colNum << "] ";
- }
- ss << ValueWriter(_context, excn).toString();
- _status = {
- JSExceptionInfo(std::move(stackStr), Status(ErrorCodes::JSInterpreterFailure, ss)),
- ss};
+ _status = Status(JSExceptionInfo(std::move(stackStr), status), ss);
} else {
_status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter");
}
}
+ JS_ClearPendingException(_context);
if (auto extraInfo = _status.extraInfo<JSExceptionInfo>()) {
str::stream reasonWithStack;
@@ -993,7 +933,7 @@ auto MozJSImplScope::ASANHandles::getThreadASANHandles() -> ASANHandles* {
void MozJSImplScope::setOOM() {
_hasOutOfMemoryException = true;
- JS_RequestInterruptCallback(_runtime);
+ JS_RequestInterruptCallback(_context);
}
void MozJSImplScope::setParentStack(std::string parentStack) {
diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h
index 7e129477b0f..83f8981a683 100644
--- a/src/mongo/scripting/mozjs/implscope.h
+++ b/src/mongo/scripting/mozjs/implscope.h
@@ -33,6 +33,7 @@
#include <jsapi.h>
#include <vm/PosixNSPR.h>
+
#include "mongo/client/dbclient_cursor.h"
#include "mongo/scripting/mozjs/bindata.h"
#include "mongo/scripting/mozjs/bson.h"
@@ -47,6 +48,7 @@
#include "mongo/scripting/mozjs/dbref.h"
#include "mongo/scripting/mozjs/engine.h"
#include "mongo/scripting/mozjs/error.h"
+#include "mongo/scripting/mozjs/freeOpToJSContext.h"
#include "mongo/scripting/mozjs/global.h"
#include "mongo/scripting/mozjs/internedstring.h"
#include "mongo/scripting/mozjs/jsthread.h"
@@ -393,9 +395,8 @@ private:
struct MozJSEntry;
friend struct MozJSEntry;
- static void _reportError(JSContext* cx, const char* message, JSErrorReport* report);
static bool _interruptCallback(JSContext* cx);
- static void _gcCallback(JSRuntime* rt, JSGCStatus status, void* data);
+ static void _gcCallback(JSContext* rt, JSGCStatus status, void* data);
bool _checkErrorState(bool success, bool reportError = true, bool assertOnError = true);
void installDBAccess();
@@ -407,7 +408,6 @@ private:
ASANHandles _asanHandles;
MozJSScriptEngine* _engine;
MozRuntime _mr;
- JSRuntime* _runtime;
JSContext* _context;
WrapType<GlobalInfo> _globalProto;
JS::HandleObject _global;
@@ -464,9 +464,10 @@ inline MozJSImplScope* getScope(JSContext* cx) {
return static_cast<MozJSImplScope*>(JS_GetContextPrivate(cx));
}
-inline MozJSImplScope* getScope(JSFreeOp* fop) {
- return static_cast<MozJSImplScope*>(JS_GetRuntimePrivate(fop->runtime()));
+inline MozJSImplScope* getScope(js::FreeOp* fop) {
+ return getScope(freeOpToJSContext(fop));
}
+
} // namespace mozjs
} // namespace mongo
diff --git a/src/mongo/scripting/mozjs/jscustomallocator.cpp b/src/mongo/scripting/mozjs/jscustomallocator.cpp
index d2d8741bca6..b74fbcdac7b 100644
--- a/src/mongo/scripting/mozjs/jscustomallocator.cpp
+++ b/src/mongo/scripting/mozjs/jscustomallocator.cpp
@@ -258,16 +258,6 @@ void* js_realloc(void* p, size_t bytes) {
[](void* ptr, size_t b) { return std::realloc(ptr, b); }, p, bytes);
}
-char* js_strdup(const char* s) {
- size_t bytes = std::strlen(s) + 1;
+void js::InitMallocAllocator() {}
- char* new_s = static_cast<char*>(js_malloc(bytes));
-
- if (!new_s) {
- return nullptr;
- }
-
- std::memcpy(new_s, s, bytes);
-
- return new_s;
-}
+void js::ShutDownMallocAllocator() {}
diff --git a/src/mongo/scripting/mozjs/jsthread.cpp b/src/mongo/scripting/mozjs/jsthread.cpp
index 9c1c7b6195a..be1ca939f55 100644
--- a/src/mongo/scripting/mozjs/jsthread.cpp
+++ b/src/mongo/scripting/mozjs/jsthread.cpp
@@ -234,7 +234,7 @@ JSThreadConfig* getConfig(JSContext* cx, JS::CallArgs args) {
} // namespace
-void JSThreadInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void JSThreadInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto config = static_cast<JSThreadConfig*>(JS_GetPrivate(obj));
if (!config)
diff --git a/src/mongo/scripting/mozjs/jsthread.h b/src/mongo/scripting/mozjs/jsthread.h
index 1bda214f44f..4ecef8097fa 100644
--- a/src/mongo/scripting/mozjs/jsthread.h
+++ b/src/mongo/scripting/mozjs/jsthread.h
@@ -47,7 +47,7 @@ namespace mozjs {
* JSThread and add our holder in as our JSThread's private member.
*/
struct JSThreadInfo : public BaseInfo {
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(init);
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index 5188c0f3888..a7dd4ee1de3 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -201,7 +201,7 @@ void setHiddenMongo(JSContext* cx,
}
} // namespace
-void MongoBase::finalize(JSFreeOp* fop, JSObject* obj) {
+void MongoBase::finalize(js::FreeOp* fop, JSObject* obj) {
auto conn = static_cast<std::shared_ptr<DBClientBase>*>(JS_GetPrivate(obj));
if (conn) {
diff --git a/src/mongo/scripting/mozjs/mongo.h b/src/mongo/scripting/mozjs/mongo.h
index f99f50b6334..699ba2c2749 100644
--- a/src/mongo/scripting/mozjs/mongo.h
+++ b/src/mongo/scripting/mozjs/mongo.h
@@ -43,7 +43,7 @@ namespace mozjs {
* info type with common code and differentiate with varying constructors.
*/
struct MongoBase : public BaseInfo {
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(auth);
diff --git a/src/mongo/scripting/mozjs/nativefunction.cpp b/src/mongo/scripting/mozjs/nativefunction.cpp
index 7354365aa80..7388794e5d4 100644
--- a/src/mongo/scripting/mozjs/nativefunction.cpp
+++ b/src/mongo/scripting/mozjs/nativefunction.cpp
@@ -89,7 +89,7 @@ void NativeFunctionInfo::call(JSContext* cx, JS::CallArgs args) {
ValueReader(cx, args.rval()).fromBSONElement(out.firstElement(), out, false);
}
-void NativeFunctionInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void NativeFunctionInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto holder = static_cast<NativeHolder*>(JS_GetPrivate(obj));
if (holder)
diff --git a/src/mongo/scripting/mozjs/nativefunction.h b/src/mongo/scripting/mozjs/nativefunction.h
index e8a4d7522c1..b4c188e0c4a 100644
--- a/src/mongo/scripting/mozjs/nativefunction.h
+++ b/src/mongo/scripting/mozjs/nativefunction.h
@@ -51,7 +51,7 @@ namespace mozjs {
*/
struct NativeFunctionInfo : public BaseInfo {
static void call(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
static const char* const inheritFrom;
static const char* const className;
diff --git a/src/mongo/scripting/mozjs/numberdecimal.cpp b/src/mongo/scripting/mozjs/numberdecimal.cpp
index 8f6ebfb21ea..c928b95c9f1 100644
--- a/src/mongo/scripting/mozjs/numberdecimal.cpp
+++ b/src/mongo/scripting/mozjs/numberdecimal.cpp
@@ -52,7 +52,7 @@ const JSFunctionSpec NumberDecimalInfo::methods[3] = {
const char* const NumberDecimalInfo::className = "NumberDecimal";
-void NumberDecimalInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void NumberDecimalInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto x = static_cast<Decimal128*>(JS_GetPrivate(obj));
if (x)
diff --git a/src/mongo/scripting/mozjs/numberdecimal.h b/src/mongo/scripting/mozjs/numberdecimal.h
index f601dbeb786..689257ba925 100644
--- a/src/mongo/scripting/mozjs/numberdecimal.h
+++ b/src/mongo/scripting/mozjs/numberdecimal.h
@@ -44,7 +44,7 @@ namespace mozjs {
struct NumberDecimalInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(toString);
diff --git a/src/mongo/scripting/mozjs/numberint.cpp b/src/mongo/scripting/mozjs/numberint.cpp
index 28994955f7b..b805a03d985 100644
--- a/src/mongo/scripting/mozjs/numberint.cpp
+++ b/src/mongo/scripting/mozjs/numberint.cpp
@@ -52,7 +52,7 @@ const JSFunctionSpec NumberIntInfo::methods[5] = {
const char* const NumberIntInfo::className = "NumberInt";
-void NumberIntInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void NumberIntInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto x = static_cast<int*>(JS_GetPrivate(obj));
if (x)
diff --git a/src/mongo/scripting/mozjs/numberint.h b/src/mongo/scripting/mozjs/numberint.h
index 3bd5e215237..edea69ebbca 100644
--- a/src/mongo/scripting/mozjs/numberint.h
+++ b/src/mongo/scripting/mozjs/numberint.h
@@ -42,7 +42,7 @@ namespace mozjs {
*/
struct NumberIntInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(toNumber);
diff --git a/src/mongo/scripting/mozjs/numberlong.cpp b/src/mongo/scripting/mozjs/numberlong.cpp
index ff60d031198..3617e1bc35a 100644
--- a/src/mongo/scripting/mozjs/numberlong.cpp
+++ b/src/mongo/scripting/mozjs/numberlong.cpp
@@ -58,7 +58,7 @@ const JSFunctionSpec NumberLongInfo::methods[6] = {
const char* const NumberLongInfo::className = "NumberLong";
-void NumberLongInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void NumberLongInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto numLong = static_cast<int64_t*>(JS_GetPrivate(obj));
if (numLong)
@@ -210,10 +210,9 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
cx,
proto,
getScope(cx)->getInternedStringId(InternedString::floatApprox),
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::floatApprox, false, NumberLongInfo>,
- nullptr)) {
+ nullptr,
+ JSPROP_ENUMERATE)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
}
@@ -222,10 +221,9 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
cx,
proto,
getScope(cx)->getInternedStringId(InternedString::top),
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::top, false, NumberLongInfo>,
- nullptr)) {
+ nullptr,
+ JSPROP_ENUMERATE)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
}
@@ -234,10 +232,9 @@ void NumberLongInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::Han
cx,
proto,
getScope(cx)->getInternedStringId(InternedString::bottom),
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::bottom, false, NumberLongInfo>,
- nullptr)) {
+ nullptr,
+ JSPROP_ENUMERATE)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
}
}
diff --git a/src/mongo/scripting/mozjs/numberlong.h b/src/mongo/scripting/mozjs/numberlong.h
index e1e6ff52774..2697be1b661 100644
--- a/src/mongo/scripting/mozjs/numberlong.h
+++ b/src/mongo/scripting/mozjs/numberlong.h
@@ -53,7 +53,7 @@ namespace mozjs {
*/
struct NumberLongInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(toNumber);
diff --git a/src/mongo/scripting/mozjs/objectwrapper.cpp b/src/mongo/scripting/mozjs/objectwrapper.cpp
index 61030ce0274..01bb79a8890 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.cpp
+++ b/src/mongo/scripting/mozjs/objectwrapper.cpp
@@ -109,29 +109,57 @@ void ObjectWrapper::Key::set(JSContext* cx, JS::HandleObject o, JS::HandleValue
void ObjectWrapper::Key::define(JSContext* cx,
JS::HandleObject o,
JS::HandleValue value,
- unsigned attrs,
- JSNative getter,
- JSNative setter) {
+ unsigned attrs) {
switch (_type) {
case Type::Field:
- if (JS_DefineProperty(cx, o, _field, value, attrs, getter, setter))
+ if (JS_DefineProperty(cx, o, _field, value, attrs))
return;
break;
case Type::Index:
- if (JS_DefineElement(cx, o, _idx, value, attrs, getter, setter))
+ if (JS_DefineElement(cx, o, _idx, value, attrs))
return;
break;
case Type::Id: {
JS::RootedId id(cx, _id);
- if (JS_DefinePropertyById(cx, o, id, value, attrs, getter, setter))
+ if (JS_DefinePropertyById(cx, o, id, value, attrs))
return;
break;
}
case Type::InternedString: {
InternedStringId id(cx, _internedString);
- if (JS_DefinePropertyById(cx, o, id, value, attrs, getter, setter))
+ if (JS_DefinePropertyById(cx, o, id, value, attrs))
+ return;
+ break;
+ }
+ }
+
+ throwCurrentJSException(cx, ErrorCodes::InternalError, "Failed to define value on a JSObject");
+}
+
+void ObjectWrapper::Key::define(
+ JSContext* cx, JS::HandleObject o, unsigned attrs, JSNative getter, JSNative setter) {
+ switch (_type) {
+ case Type::Field:
+ if (JS_DefineProperty(cx, o, _field, getter, setter, attrs))
+ return;
+ break;
+ case Type::Index:
+ if (JS_DefineElement(cx, o, _idx, getter, setter, attrs))
+ return;
+ break;
+ case Type::Id: {
+ JS::RootedId id(cx, _id);
+
+ if (JS_DefinePropertyById(cx, o, id, getter, setter, attrs))
+ return;
+ break;
+ }
+ case Type::InternedString: {
+ InternedStringId id(cx, _internedString);
+
+ if (JS_DefinePropertyById(cx, o, id, getter, setter, attrs))
return;
break;
}
@@ -390,9 +418,12 @@ void ObjectWrapper::setPrototype(JS::HandleObject object) {
throwCurrentJSException(_context, ErrorCodes::InternalError, "Failed to set prototype");
}
-void ObjectWrapper::defineProperty(
- Key key, JS::HandleValue val, unsigned attrs, JSNative getter, JSNative setter) {
- key.define(_context, _object, val, attrs, getter, setter);
+void ObjectWrapper::defineProperty(Key key, JS::HandleValue val, unsigned attrs) {
+ key.define(_context, _object, val, attrs);
+}
+
+void ObjectWrapper::defineProperty(Key key, unsigned attrs, JSNative getter, JSNative setter) {
+ key.define(_context, _object, attrs, getter, setter);
}
void ObjectWrapper::deleteProperty(Key key) {
diff --git a/src/mongo/scripting/mozjs/objectwrapper.h b/src/mongo/scripting/mozjs/objectwrapper.h
index 10e5233f5b2..ddbba2f5c17 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.h
+++ b/src/mongo/scripting/mozjs/objectwrapper.h
@@ -86,12 +86,9 @@ public:
void set(JSContext* cx, JS::HandleObject o, JS::HandleValue value);
bool has(JSContext* cx, JS::HandleObject o);
bool hasOwn(JSContext* cx, JS::HandleObject o);
- void define(JSContext* cx,
- JS::HandleObject o,
- JS::HandleValue value,
- unsigned attrs,
- JSNative getter,
- JSNative setter);
+ void define(
+ JSContext* cx, JS::HandleObject o, unsigned attrs, JSNative getter, JSNative setter);
+ void define(JSContext* cx, JS::HandleObject o, JS::HandleValue value, unsigned attrs);
void del(JSContext* cx, JS::HandleObject o);
std::string toString(JSContext* cx);
StringData toStringData(JSContext* cx, JSStringWrapper* jsstr);
@@ -130,11 +127,8 @@ public:
/**
* See JS_DefineProperty for what sort of attributes might be useful
*/
- void defineProperty(Key key,
- JS::HandleValue value,
- unsigned attrs,
- JSNative getter = nullptr,
- JSNative setter = nullptr);
+ void defineProperty(Key key, unsigned attrs, JSNative getter, JSNative setter);
+ void defineProperty(Key key, JS::HandleValue value, unsigned attrs);
void deleteProperty(Key key);
diff --git a/src/mongo/scripting/mozjs/oid.cpp b/src/mongo/scripting/mozjs/oid.cpp
index 290ba4e99ea..a3b822ba3dc 100644
--- a/src/mongo/scripting/mozjs/oid.cpp
+++ b/src/mongo/scripting/mozjs/oid.cpp
@@ -51,7 +51,7 @@ const JSFunctionSpec OIDInfo::methods[3] = {
const char* const OIDInfo::className = "ObjectId";
-void OIDInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void OIDInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto oid = static_cast<OID*>(JS_GetPrivate(obj));
if (oid) {
@@ -125,10 +125,9 @@ void OIDInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObje
if (!JS_DefinePropertyById(cx,
proto,
getScope(cx)->getInternedStringId(InternedString::str),
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
smUtils::wrapConstrainedMethod<Functions::getter, true, OIDInfo>,
- nullptr)) {
+ nullptr,
+ JSPROP_ENUMERATE)) {
uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
}
}
diff --git a/src/mongo/scripting/mozjs/oid.h b/src/mongo/scripting/mozjs/oid.h
index 947b06faa01..09356bf3085 100644
--- a/src/mongo/scripting/mozjs/oid.h
+++ b/src/mongo/scripting/mozjs/oid.h
@@ -42,7 +42,7 @@ namespace mozjs {
*/
struct OIDInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(getter);
diff --git a/src/mongo/scripting/mozjs/session.cpp b/src/mongo/scripting/mozjs/session.cpp
index 1899d1e83c4..950c75378af 100644
--- a/src/mongo/scripting/mozjs/session.cpp
+++ b/src/mongo/scripting/mozjs/session.cpp
@@ -143,7 +143,7 @@ void endSession(SessionHolder* holder) {
} // namespace
-void SessionInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void SessionInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto holder = getHolder(obj);
if (holder) {
diff --git a/src/mongo/scripting/mozjs/session.h b/src/mongo/scripting/mozjs/session.h
index 8b00d77aff4..4fcf975b87a 100644
--- a/src/mongo/scripting/mozjs/session.h
+++ b/src/mongo/scripting/mozjs/session.h
@@ -43,7 +43,7 @@ namespace mozjs {
* from C++. Current callers are all via the Mongo object.
*/
struct SessionInfo : public BaseInfo {
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(end);
diff --git a/src/mongo/scripting/mozjs/status.cpp b/src/mongo/scripting/mozjs/status.cpp
index 0062799e839..0fc7e5e3df3 100644
--- a/src/mongo/scripting/mozjs/status.cpp
+++ b/src/mongo/scripting/mozjs/status.cpp
@@ -67,25 +67,24 @@ void MongoStatusInfo::fromStatus(JSContext* cx, Status status, JS::MutableHandle
JS::RootedObject thisv(cx);
scope->getProto<MongoStatusInfo>().newObjectWithProto(&thisv, error);
ObjectWrapper thisvObj(cx, thisv);
- thisvObj.defineProperty(
- InternedString::code,
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
- smUtils::wrapConstrainedMethod<Functions::code, false, MongoStatusInfo>);
+ thisvObj.defineProperty(InternedString::code,
+ JSPROP_ENUMERATE,
+ smUtils::wrapConstrainedMethod<Functions::code, false, MongoStatusInfo>,
+ nullptr);
thisvObj.defineProperty(
InternedString::reason,
- undef,
- JSPROP_ENUMERATE | JSPROP_SHARED,
- smUtils::wrapConstrainedMethod<Functions::reason, false, MongoStatusInfo>);
+ JSPROP_ENUMERATE,
+ smUtils::wrapConstrainedMethod<Functions::reason, false, MongoStatusInfo>,
+ nullptr);
// We intentionally omit JSPROP_ENUMERATE to match how Error.prototype.stack is a non-enumerable
// property.
thisvObj.defineProperty(
InternedString::stack,
- undef,
- JSPROP_SHARED,
- smUtils::wrapConstrainedMethod<Functions::stack, false, MongoStatusInfo>);
+ 0,
+ smUtils::wrapConstrainedMethod<Functions::stack, false, MongoStatusInfo>,
+ nullptr);
JS_SetPrivate(thisv, scope->trackedNew<Status>(std::move(status)));
@@ -102,7 +101,7 @@ void MongoStatusInfo::construct(JSContext* cx, JS::CallArgs args) {
args.rval().set(out);
}
-void MongoStatusInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+void MongoStatusInfo::finalize(js::FreeOp* fop, JSObject* obj) {
auto status = static_cast<Status*>(JS_GetPrivate(obj));
if (status)
@@ -138,7 +137,8 @@ void MongoStatusInfo::Functions::stack::call(JSContext* cx, JS::CallArgs args) {
.fromStringData(extraInfo->stack + parentWrapper.getString(InternedString::stack));
// We redefine the "stack" property as the combined JavaScript stacktrace. It is important
- // that we omit JSPROP_SHARED to the thisvObj.defineProperty() call in order to have
+ // that we omit (TODO/FIXME, no more JSPROP_SHARED) JSPROP_SHARED to the
+ // thisvObj.defineProperty() call in order to have
// SpiderMonkey allocate memory for the string value. We also intentionally omit
// JSPROP_ENUMERATE to match how Error.prototype.stack is a non-enumerable property.
ObjectWrapper thisvObj(cx, args.thisv());
diff --git a/src/mongo/scripting/mozjs/status.h b/src/mongo/scripting/mozjs/status.h
index b738605800f..d8d2f875fb8 100644
--- a/src/mongo/scripting/mozjs/status.h
+++ b/src/mongo/scripting/mozjs/status.h
@@ -48,7 +48,7 @@ namespace mozjs {
*/
struct MongoStatusInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
- static void finalize(JSFreeOp* fop, JSObject* obj);
+ static void finalize(js::FreeOp* fop, JSObject* obj);
struct Functions {
MONGO_DECLARE_JS_FUNCTION(code);
diff --git a/src/mongo/scripting/mozjs/wraptype.h b/src/mongo/scripting/mozjs/wraptype.h
index e4912d04c7c..0160b1c029f 100644
--- a/src/mongo/scripting/mozjs/wraptype.h
+++ b/src/mongo/scripting/mozjs/wraptype.h
@@ -64,7 +64,7 @@
};
#define MONGO_ATTACH_JS_FUNCTION_WITH_FLAGS(name, flags) \
- JS_FS(#name, smUtils::wrapFunction<Functions::name>, 0, flags)
+ JS_FN(#name, smUtils::wrapFunction<Functions::name>, 0, flags)
#define MONGO_ATTACH_JS_FUNCTION(name) MONGO_ATTACH_JS_FUNCTION_WITH_FLAGS(name, 0)
@@ -161,7 +161,11 @@ bool enumerate(JSContext* cx,
};
template <typename T>
-bool getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) {
+bool getProperty(JSContext* cx,
+ JS::HandleObject obj,
+ JS::HandleValue receiver,
+ JS::HandleId id,
+ JS::MutableHandleValue vp) {
if (JSID_IS_SYMBOL(id)) {
// Just default to the SpiderMonkey's standard implementations for Symbol methods
vp.setUndefined();
@@ -169,7 +173,7 @@ bool getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::Mutab
}
try {
- T::getProperty(cx, obj, id, vp);
+ T::getProperty(cx, obj, id, receiver, vp);
return true;
} catch (...) {
mongoToJSException(cx);
@@ -192,10 +196,11 @@ template <typename T>
bool setProperty(JSContext* cx,
JS::HandleObject obj,
JS::HandleId id,
- JS::MutableHandleValue vp,
+ JS::HandleValue vp,
+ JS::HandleValue receiver,
JS::ObjectOpResult& result) {
try {
- T::setProperty(cx, obj, id, vp, result);
+ T::setProperty(cx, obj, id, vp, receiver, result);
return true;
} catch (...) {
mongoToJSException(cx);
@@ -231,34 +236,53 @@ public:
_constructor(),
_jsclass({T::className,
T::classFlags,
- T::addProperty != BaseInfo::addProperty ? smUtils::addProperty<T> : nullptr,
- T::delProperty != BaseInfo::delProperty ? smUtils::delProperty<T> : nullptr,
- T::getProperty != BaseInfo::getProperty ? smUtils::getProperty<T> : nullptr,
- T::setProperty != BaseInfo::setProperty ? smUtils::setProperty<T> : nullptr,
- // We don't use the regular enumerate because we want the fancy new one
- nullptr,
- T::resolve != BaseInfo::resolve ? smUtils::resolve<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,
- T::construct != BaseInfo::construct ? smUtils::construct<T> : nullptr,
- nullptr}) {
- _installEnumerate(T::enumerate != BaseInfo::enumerate ? smUtils::enumerate<T> : nullptr);
+ &_jsclassOps,
+ JS_NULL_CLASS_SPEC,
+ JS_NULL_CLASS_EXT,
+ &_jsoOps}),
+ _jsclassOps({T::addProperty != BaseInfo::addProperty ? smUtils::addProperty<T> : nullptr,
+ T::delProperty != BaseInfo::delProperty ? smUtils::delProperty<T> : nullptr,
+ nullptr, // enumerate
+ T::enumerate != BaseInfo::enumerate ? smUtils::enumerate<T>
+ : nullptr, // newEnumerate
+ T::resolve != BaseInfo::resolve ? smUtils::resolve<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,
+ T::construct != BaseInfo::construct ? smUtils::construct<T> : nullptr,
+ nullptr}), // trace
+ _jsoOps({
+ nullptr, // lookupProperty
+ nullptr, // defineProperty
+ nullptr, // hasProperty
+ T::getProperty != BaseInfo::getProperty ? smUtils::getProperty<T>
+ : nullptr, // getProperty
+ T::setProperty != BaseInfo::setProperty ? smUtils::setProperty<T>
+ : nullptr, // setProperty
+ nullptr, // getOwnPropertyDescriptor
+ nullptr, // deleteProperty
+ nullptr, // getElements
+ nullptr // funToString
+ }) {
// The global object is different. We need it for basic setup
// before the other types are installed. Might as well just do it
// in the constructor.
if (T::classFlags & JSCLASS_GLOBAL_FLAGS) {
- _jsclass.trace = JS_GlobalObjectTraceHook;
+ _jsclassOps.trace = JS_GlobalObjectTraceHook;
JS::RootedObject proto(_context);
JSAutoRequest ar(_context);
+ JS::CompartmentOptions options;
_proto.init(_context,
- _assertPtr(JS_NewGlobalObject(
- _context, &_jsclass, nullptr, JS::DontFireOnNewGlobalHook)));
+ _assertPtr(JS_NewGlobalObject(_context,
+ js::Jsvalify(&_jsclass),
+ nullptr,
+ JS::DontFireOnNewGlobalHook,
+ options)));
JSAutoCompartment ac(_context, _proto);
_installFunctions(_proto, T::freeFunctions);
@@ -290,7 +314,7 @@ public:
* types without a constructor or inside the constructor
*/
void newObject(JS::MutableHandleObject out) {
- out.set(_assertPtr(JS_NewObjectWithGivenProto(_context, &_jsclass, _proto)));
+ out.set(_assertPtr(JS_NewObjectWithGivenProto(_context, js::Jsvalify(&_jsclass), _proto)));
}
void newObject(JS::MutableHandleValue out) {
@@ -301,7 +325,7 @@ public:
}
void newObjectWithProto(JS::MutableHandleObject out, JS::HandleObject proto) {
- out.set(_assertPtr(JS_NewObjectWithGivenProto(_context, &_jsclass, proto)));
+ out.set(_assertPtr(JS_NewObjectWithGivenProto(_context, js::Jsvalify(&_jsclass), proto)));
}
void newObjectWithProto(JS::MutableHandleValue out, JS::HandleObject proto) {
@@ -346,7 +370,7 @@ public:
// instanceOf doesn't go up the prototype tree. It's a lower level more specific match
bool instanceOf(JS::HandleObject obj) {
- return JS_InstanceOf(_context, obj, &_jsclass, nullptr);
+ return JS_InstanceOf(_context, obj, js::Jsvalify(&_jsclass), nullptr);
}
bool instanceOf(JS::HandleValue value) {
@@ -359,7 +383,7 @@ public:
}
const JSClass* getJSClass() const {
- return &_jsclass;
+ return js::Jsvalify(&_jsclass);
}
JS::HandleObject getProto() const {
@@ -383,7 +407,7 @@ private:
_context,
global,
parent,
- &_jsclass,
+ js::Jsvalify(&_jsclass),
T::construct != BaseInfo::construct ? smUtils::construct<T> : nullptr,
0,
nullptr,
@@ -405,7 +429,7 @@ private:
// See newObject() for why we have to do this dance with the explicit
// SetPrototype
- _proto.init(_context, _assertPtr(JS_NewObject(_context, &_jsclass)));
+ _proto.init(_context, _assertPtr(JS_NewObject(_context, js::Jsvalify(&_jsclass))));
if (parent.get() && !JS_SetPrototype(_context, _proto, parent))
throwCurrentJSException(
_context, ErrorCodes::JSInterpreterFailure, "Failed to set prototype");
@@ -475,23 +499,6 @@ private:
_context, ErrorCodes::JSInterpreterFailure, "Failed to define functions");
}
- // We have to do this awkward dance to set the new style enumeration.
- // You used to be able to set this with JSCLASS_NEW_ENUMERATE in class
- // flags, in the future you'll probably only set ObjectOps, but for now
- // we have this. There are a host of static_asserts in js/Class.h that
- // 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&, bool);
- void _installEnumerate(enumerateT enumerate) {
- if (!enumerate)
- return;
-
- auto implClass = reinterpret_cast<js::Class*>(&_jsclass);
-
- implClass->ops.enumerate = enumerate;
- }
-
// This is for inheriting from something other than Object
void _inheritFrom(const char* name, JS::HandleObject global, JS::MutableHandleObject out) {
if (!name)
@@ -548,7 +555,9 @@ private:
JSContext* _context;
JS::PersistentRootedObject _proto;
JS::PersistentRootedObject _constructor;
- JSClass _jsclass;
+ js::Class _jsclass;
+ js::ClassOps _jsclassOps;
+ js::ObjectOps _jsoOps;
};
} // namespace mozjs
diff --git a/src/mongo/shell/error_codes.tpl.js b/src/mongo/shell/error_codes.tpl.js
index 767a48d1ae3..f4299deae3f 100644
--- a/src/mongo/shell/error_codes.tpl.js
+++ b/src/mongo/shell/error_codes.tpl.js
@@ -31,7 +31,7 @@
var {ErrorCodes, ErrorCodeStrings} = (function() {
const handler = {
get: function(obj, prop) {
- if (prop !== Symbol.toPrimitive && prop in obj === false && prop in Object === false) {
+ if (typeof prop !== "symbol" && prop in obj === false && prop in Object === false) {
throw new Error('Unknown Error Code: ' + prop.toString());
}
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index 4b3f95db88d..2f25605536d 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -89,63 +89,66 @@ Mongo.prototype.getDBs = function(driverSession = this._getDefaultSession(),
filter = undefined,
nameOnly = undefined,
authorizedDatabases = undefined) {
- 'use strict';
- let cmdObj = {listDatabases: 1};
- if (filter !== undefined) {
- cmdObj.filter = filter;
- }
- if (nameOnly !== undefined) {
- cmdObj.nameOnly = nameOnly;
- }
- if (authorizedDatabases !== undefined) {
- cmdObj.authorizedDatabases = authorizedDatabases;
- }
+ return function(driverSession, filter, nameOnly, authorizedDatabases) {
+ 'use strict';
- if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
- }
+ let cmdObj = {listDatabases: 1};
+ if (filter !== undefined) {
+ cmdObj.filter = filter;
+ }
+ if (nameOnly !== undefined) {
+ cmdObj.nameOnly = nameOnly;
+ }
+ if (authorizedDatabases !== undefined) {
+ cmdObj.authorizedDatabases = authorizedDatabases;
+ }
- const res = this.adminCommand(cmdObj);
- if (!res.ok) {
- // If "Unauthorized" was returned by the back end and we haven't explicitly
- // asked for anything difficult to provide from userspace, then we can
- // fallback on inspecting the user's permissions.
- // This means that:
- // * filter must be undefined, as reimplementing that logic is out of scope.
- // * nameOnly must not be false as we can't infer size information.
- // * authorizedDatabases must not be false as those are the only DBs we can infer.
- // Note that if the above are valid and we get Unauthorized, that also means
- // that we MUST be talking to a pre-4.0 mongod.
- //
- // Like the server response mode, this path will return a simple list of
- // names if nameOnly is specified as true.
- // If nameOnly is undefined, we come as close as we can to what the
- // server would return by supplying the databases key of the returned
- // object. Other information is unavailable.
- if ((res.code === ErrorCodes.Unauthorized) && (filter === undefined) &&
- (nameOnly !== false) && (authorizedDatabases !== false)) {
- const names = this._getDatabaseNamesFromPrivileges();
- if (nameOnly === true) {
- return names;
- } else {
- return {
- databases: names.map(function(x) {
- return {name: x};
- }),
- };
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
+
+ const res = this.adminCommand(cmdObj);
+ if (!res.ok) {
+ // If "Unauthorized" was returned by the back end and we haven't explicitly
+ // asked for anything difficult to provide from userspace, then we can
+ // fallback on inspecting the user's permissions.
+ // This means that:
+ // * filter must be undefined, as reimplementing that logic is out of scope.
+ // * nameOnly must not be false as we can't infer size information.
+ // * authorizedDatabases must not be false as those are the only DBs we can infer.
+ // Note that if the above are valid and we get Unauthorized, that also means
+ // that we MUST be talking to a pre-4.0 mongod.
+ //
+ // Like the server response mode, this path will return a simple list of
+ // names if nameOnly is specified as true.
+ // If nameOnly is undefined, we come as close as we can to what the
+ // server would return by supplying the databases key of the returned
+ // object. Other information is unavailable.
+ if ((res.code === ErrorCodes.Unauthorized) && (filter === undefined) &&
+ (nameOnly !== false) && (authorizedDatabases !== false)) {
+ const names = this._getDatabaseNamesFromPrivileges();
+ if (nameOnly === true) {
+ return names;
+ } else {
+ return {
+ databases: names.map(function(x) {
+ return {name: x};
+ }),
+ };
+ }
}
+ throw _getErrorWithCode(res, "listDatabases failed:" + tojson(res));
}
- throw _getErrorWithCode(res, "listDatabases failed:" + tojson(res));
- }
- if (nameOnly) {
- return res.databases.map(function(db) {
- return db.name;
- });
- }
+ if (nameOnly) {
+ return res.databases.map(function(db) {
+ return db.name;
+ });
+ }
- return res;
+ return res;
+ }.call(this, driverSession, filter, nameOnly, authorizedDatabases);
};
Mongo.prototype.adminCommand = function(cmd) {
diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js
index 8f1522b7618..ea8766968e6 100644
--- a/src/mongo/shell/replsettest.js
+++ b/src/mongo/shell/replsettest.js
@@ -484,7 +484,7 @@ var ReplSetTest = function(opts) {
member._id = i;
member.host = this.host;
- if (!member.host.contains('/')) {
+ if (!member.host.includes('/')) {
member.host += ":" + this.ports[i];
}
@@ -2279,6 +2279,15 @@ var ReplSetTest = function(opts) {
// Turn off periodic noop writes for replica sets by default.
options.setParameter = options.setParameter || {};
+ if (typeof(options.setParameter) === "string") {
+ var eqIdx = options.setParameter.indexOf("=");
+ if (eqIdx != -1) {
+ var param = options.setParameter.substring(0, eqIdx);
+ var value = options.setParameter.substring(eqIdx + 1);
+ options.setParameter = {};
+ options.setParameter[param] = value;
+ }
+ }
options.setParameter.writePeriodicNoops = options.setParameter.writePeriodicNoops || false;
// We raise the number of initial sync connect attempts for tests that disallow chaining.