summaryrefslogtreecommitdiff
path: root/src/mongo/scripting
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2015-10-06 20:42:23 -0400
committerJason Carey <jcarey@argv.me>2015-10-06 20:42:23 -0400
commitcad0c421371e55fdf65c0be4badd23120bec72c1 (patch)
tree104284cbb97a1810f34269ae11738b1c39c6e767 /src/mongo/scripting
parentb0c83fe82db91e239b706c21636e9aae318e640f (diff)
downloadmongo-cad0c421371e55fdf65c0be4badd23120bec72c1.tar.gz
SERVER-19977 Re-work JS ObjectID
Rather than storing a string with the encoded oid, just store a pointer to the oid and convert it to a string on demand for "str" access.
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r--src/mongo/scripting/mozjs/oid.cpp72
-rw-r--r--src/mongo/scripting/mozjs/oid.h10
-rw-r--r--src/mongo/scripting/mozjs/valuereader.cpp6
3 files changed, 67 insertions, 21 deletions
diff --git a/src/mongo/scripting/mozjs/oid.cpp b/src/mongo/scripting/mozjs/oid.cpp
index 8c0debaccc1..e24dd3f0aca 100644
--- a/src/mongo/scripting/mozjs/oid.cpp
+++ b/src/mongo/scripting/mozjs/oid.cpp
@@ -42,46 +42,86 @@ namespace mongo {
namespace mozjs {
const JSFunctionSpec OIDInfo::methods[2] = {
- MONGO_ATTACH_JS_CONSTRAINED_METHOD(toString, OIDInfo), JS_FS_END,
+ MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(toString, OIDInfo), JS_FS_END,
};
const char* const OIDInfo::className = "ObjectId";
-void OIDInfo::Functions::toString::call(JSContext* cx, JS::CallArgs args) {
- ObjectWrapper o(cx, args.thisv());
+void OIDInfo::finalize(JSFreeOp* fop, JSObject* obj) {
+ auto oid = static_cast<OID*>(JS_GetPrivate(obj));
- if (!o.hasField("str"))
- uasserted(ErrorCodes::BadValue, "Must have \"str\" field");
+ if (oid) {
+ delete oid;
+ }
+}
- JS::RootedValue value(cx);
- o.getValue("str", &value);
+void OIDInfo::Functions::toString::call(JSContext* cx, JS::CallArgs args) {
+ auto oid = static_cast<OID*>(JS_GetPrivate(args.thisv().toObjectOrNull()));
- std::string str = str::stream() << "ObjectId(\"" << ValueWriter(cx, value).toString() << "\")";
+ std::string str = str::stream() << "ObjectId(\"" << oid->toString() << "\")";
ValueReader(cx, args.rval()).fromStringData(str);
}
-void OIDInfo::construct(JSContext* cx, JS::CallArgs args) {
- auto scope = getScope(cx);
+void OIDInfo::Functions::getter::call(JSContext* cx, JS::CallArgs args) {
+ auto oid = static_cast<OID*>(JS_GetPrivate(args.thisv().toObjectOrNull()));
- auto oid = stdx::make_unique<OID>();
+ ValueReader(cx, args.rval()).fromStringData(oid->toString());
+}
+void OIDInfo::construct(JSContext* cx, JS::CallArgs args) {
+ OID oid;
if (args.length() == 0) {
- oid->init();
+ oid.init();
} else {
auto str = ValueWriter(cx, args.get(0)).toString();
Scope::validateObjectIdString(str);
- oid->init(str);
+ oid.init(str);
}
+ make(cx, oid, args.rval());
+}
+
+void OIDInfo::make(JSContext* cx, const OID& oid, JS::MutableHandleValue out) {
+ auto scope = getScope(cx);
+
+ auto oidHolder = stdx::make_unique<OID>(oid);
JS::RootedObject thisv(cx);
scope->getProto<OIDInfo>().newObject(&thisv);
- ObjectWrapper o(cx, thisv);
+ JS_SetPrivate(thisv, oidHolder.release());
+
+ out.setObjectOrNull(thisv);
+}
+
+OID OIDInfo::getOID(JSContext* cx, JS::HandleValue value) {
+ JS::RootedObject obj(cx, value.toObjectOrNull());
+ return getOID(cx, obj);
+}
- o.setString("str", oid->toString());
+OID OIDInfo::getOID(JSContext* cx, JS::HandleObject object) {
+ auto oid = static_cast<OID*>(JS_GetPrivate(object));
- args.rval().setObjectOrNull(thisv);
+ if (oid) {
+ return *oid;
+ }
+
+ uasserted(ErrorCodes::BadValue, "Can't call getOID on OID prototype");
+}
+
+void OIDInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto) {
+ JS::RootedValue undef(cx);
+ undef.setUndefined();
+
+ if (!JS_DefinePropertyById(cx,
+ proto,
+ getScope(cx)->getInternedStringId(InternedString::str),
+ undef,
+ JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_SHARED,
+ smUtils::wrapConstrainedMethod<Functions::getter, true, OIDInfo>,
+ nullptr)) {
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_DefinePropertyById");
+ }
}
} // namespace mozjs
diff --git a/src/mongo/scripting/mozjs/oid.h b/src/mongo/scripting/mozjs/oid.h
index 8171d2d2aac..3d723b97003 100644
--- a/src/mongo/scripting/mozjs/oid.h
+++ b/src/mongo/scripting/mozjs/oid.h
@@ -40,14 +40,24 @@ namespace mozjs {
*/
struct OIDInfo : public BaseInfo {
static void construct(JSContext* cx, JS::CallArgs args);
+ static void finalize(JSFreeOp* fop, JSObject* obj);
struct Functions {
+ MONGO_DECLARE_JS_FUNCTION(getter);
MONGO_DECLARE_JS_FUNCTION(toString);
};
static const JSFunctionSpec methods[2];
+ static const unsigned classFlags = JSCLASS_HAS_PRIVATE;
+
static const char* const className;
+
+ static void postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto);
+
+ static void make(JSContext* cx, const OID& oid, JS::MutableHandleValue out);
+ static OID getOID(JSContext* cx, JS::HandleValue value);
+ static OID getOID(JSContext* cx, JS::HandleObject object);
};
} // namespace mozjs
diff --git a/src/mongo/scripting/mozjs/valuereader.cpp b/src/mongo/scripting/mozjs/valuereader.cpp
index 71be53c6ff2..b78ed461297 100644
--- a/src/mongo/scripting/mozjs/valuereader.cpp
+++ b/src/mongo/scripting/mozjs/valuereader.cpp
@@ -66,11 +66,7 @@ void ValueReader::fromBSONElement(const BSONElement& elem, const BSONObj& parent
fromStringData(elem.valueStringData());
return;
case mongo::jstOID: {
- JS::AutoValueArray<1> args(_context);
-
- ValueReader(_context, args[0]).fromStringData(elem.OID().toString());
-
- scope->getProto<OIDInfo>().newInstance(args, _value);
+ OIDInfo::make(_context, elem.OID(), _value);
return;
}
case mongo::NumberDouble: