std::string ValueWriter::typeAsString() { if (_value.isNull()) return "null"; if (_value.isUndefined()) return "undefined"; if (_value.isString()) return "string"; if (JS_IsArrayObject(_context, _value)) return "array"; if (_value.isBoolean()) return "boolean"; if (_value.isNumber()) return "number"; if (_value.isObject()) { JS::RootedObject obj(_context, _value.toObjectOrNull()); if (JS_IsArrayObject(_context, obj)) return "array"; if (JS_ObjectIsDate(_context, obj)) return "date"; if (JS_ObjectIsFunction(_context, obj)) return "function"; return ObjectWrapper(_context, _value).getClassName(); } uasserted(ErrorCodes::BadValue, "unable to get type"); }
void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorReport* report) { auto scope = getScope(cx); if (!JSREPORT_IS_WARNING(report->flags)) { str::stream ss; ss << message; // 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); ObjectWrapper(cx, excn).getValue("stack", &stack); auto str = ValueWriter(cx, stack).toString(); if (str.empty()) { ss << " @" << report->filename << ":" << report->lineno << ":" << report->column << "\n"; } else { ss << " :\n" << str; } } scope->_status = Status( JSErrorReportToStatus(cx, report, ErrorCodes::JSInterpreterFailure, message).code(), ss); } }
void SuifPrinterModule::print(ostream& output, const Address what, const MetaClass* type, int _indent ) { print2(output, ObjectWrapper(what, type), emptyLString, _indent, 0); output <<endl; }
BSONObj ValueWriter::toBSON() { if (!_value.isObject()) return BSONObj(); JS::RootedObject obj(_context, _value.toObjectOrNull()); return ObjectWrapper(_context, obj).toBSON(); }
void MaxKeyInfo::postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto) { ObjectWrapper protoWrapper(cx, proto); JS::RootedValue value(cx); getScope(cx)->getProto<MaxKeyInfo>().newObject(&value); ObjectWrapper(cx, global).setValue(InternedString::MaxKey, value); protoWrapper.setValue(InternedString::singleton, value); }
void MozJSImplScope::setFunction(const char* field, const char* code) { MozJSEntry entry(this); JS::RootedValue fun(_context); _MozJSCreateFunction(code, getFunctionCache().size() + 1, &fun); ObjectWrapper(_context, _global).setValue(field, fun); }
//---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void SuifPrinterModule::print(ostream& output, const SuifObject*rootNode) { suif_assert(rootNode != NULL); //const MetaClass *type = rootNode->get_meta_class(); int _indent = 2; print2(output, ObjectWrapper(rootNode), emptyLString, _indent); output <<endl; }
std::string ObjectWrapper::getClassName() { auto jsclass = JS_GetClass(_object); if (jsclass) return jsclass->name; JS::RootedValue ctor(_context); getValue(InternedString::constructor, &ctor); return ObjectWrapper(_context, ctor).getString(InternedString::name); }
void MozJSImplScope::injectNative(const char* field, NativeFunction func, void* data) { MozJSEntry entry(this); JS::RootedObject obj(_context); NativeFunctionInfo::make(_context, &obj, func, data); JS::RootedValue value(_context); value.setObjectOrNull(obj); ObjectWrapper(_context, _global).setValue(field, value); }
void SuifPrinterModule::print(ostream& output) { const FileSetBlock *f = _suif_env->get_file_set_block(); if (f) { print2(output, ObjectWrapper(f), emptyLString); output<<endl; } else output << "Suifprinter: Unable to get RootNode FileSetBlock - NULL\n"; }
void JSThreadInfo::Functions::init::call(JSContext* cx, JS::CallArgs args) { auto scope = getScope(cx); JS::RootedObject obj(cx); scope->getProto<JSThreadInfo>().newObject(&obj); JSThreadConfig* config = new JSThreadConfig(cx, args); JS_SetPrivate(obj, config); ObjectWrapper(cx, args.thisv()).setObject("_JSThreadConfig", obj); args.rval().setUndefined(); }
void NativeFunctionInfo::call(JSContext* cx, JS::CallArgs args) { auto holder = getHolder(args); if (!holder) { // Calling the prototype args.rval().setUndefined(); return; } JS::RootedObject robj(cx, JS_NewArrayObject(cx, args)); if (!robj) { uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_NewArrayObject"); } BSONObj out = holder->_func(ObjectWrapper(cx, robj).toBSON(), holder->_ctx); ValueReader(cx, args.rval()).fromBSONElement(out.firstElement(), out, false); }
void MozJSImplScope::installBSONTypes() { _binDataProto.install(_global); _bsonProto.install(_global); _dbPointerProto.install(_global); _dbRefProto.install(_global); _maxKeyProto.install(_global); _minKeyProto.install(_global); _nativeFunctionProto.install(_global); _numberIntProto.install(_global); _numberLongProto.install(_global); _objectProto.install(_global); _oidProto.install(_global); _regExpProto.install(_global); _timestampProto.install(_global); // This builtin map is a javascript 6 thing. We want our version. so // take theirs out ObjectWrapper(_context, _global).deleteProperty("Map"); }
void BSONInfo::setProperty( JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp) { auto holder = getHolder(obj); if (holder) { if (holder->_readOnly) { uasserted(ErrorCodes::BadValue, "Read only object"); } auto iter = holder->_removed.find(IdWrapper(cx, id).toString()); if (iter != holder->_removed.end()) { holder->_removed.erase(iter); } holder->_altered = true; } ObjectWrapper(cx, obj).defineProperty(id, vp, JSPROP_ENUMERATE); }
bool MozJSImplScope::exec(StringData code, const std::string& name, bool printResult, bool reportError, bool assertOnError, int timeoutMs) { MozJSEntry entry(this); JS::CompileOptions co(_context); setCompileOptions(&co); co.setFile(name.c_str()); JS::RootedScript script(_context); bool success = JS::Compile(_context, _global, co, code.rawData(), code.size(), &script); if (_checkErrorState(success, reportError, assertOnError)) return false; if (timeoutMs) _engine->getDeadlineMonitor().startDeadline(this, timeoutMs); JS::RootedValue out(_context); success = JS_ExecuteScript(_context, _global, script, &out); if (timeoutMs) _engine->getDeadlineMonitor().stopDeadline(this); if (_checkErrorState(success, reportError, assertOnError)) return false; ObjectWrapper(_context, _global).setValue(kExecResult, out); if (printResult && !out.isUndefined()) { // appears to only be used by shell std::cout << ValueWriter(_context, out).toString() << std::endl; } return true; }
void DBQueryInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) { *resolvedp = false; IdWrapper wid(cx, id); // We only use this for index access if (!wid.isInt()) { return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::InternalError, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); JS::RootedValue arrayAccess(cx); parentWrapper.getValue(InternedString::arrayAccess, &arrayAccess); if (arrayAccess.isObject() && JS_ObjectIsFunction(cx, arrayAccess.toObjectOrNull())) { JS::AutoValueArray<1> args(cx); args[0].setInt32(wid.toInt32()); JS::RootedValue vp(cx); ObjectWrapper(cx, obj).callMethod(arrayAccess, args, &vp); if (!vp.isNullOrUndefined()) { ObjectWrapper o(cx, obj); // Assumes the user won't modify the contents of what DBQuery::arrayAccess returns // otherwise we need to install a getter. o.defineProperty(id, vp, 0); } *resolvedp = true; } }
bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool assertOnError) { if (success) return false; if (_quickExit) return false; if (_status.isOK()) { JS::RootedValue excn(_context); if (JS_GetPendingException(_context, &excn) && excn.isObject()) { str::stream ss; JS::RootedValue stack(_context); ObjectWrapper(_context, excn).getValue("stack", &stack); ss << ValueWriter(_context, excn).toString() << " :\n" << ValueWriter(_context, stack).toString(); _status = Status(ErrorCodes::JSInterpreterFailure, ss); } else { _status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter"); } } _error = _status.reason(); if (reportError) error() << _error << std::endl; // Clear the status state auto status = std::move(_status); if (assertOnError) { // Throw if necessary uassertStatusOK(status); } return true; }
void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorReport* report) { auto scope = getScope(cx); if (!JSREPORT_IS_WARNING(report->flags)) { str::stream ss; ss << message; // 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); ObjectWrapper(cx, excn).getValue("stack", &stack); ss << " :\n" << ValueWriter(cx, stack).toString(); } scope->_status = Status(report->errorNumber ? static_cast<ErrorCodes::Error>(report->errorNumber) : ErrorCodes::JSInterpreterFailure, ss); } }
Decimal128 MozJSImplScope::getNumberDecimal(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).getNumberDecimal(field); }
int MozJSImplScope::invoke(ScriptingFunction func, const BSONObj* argsObject, const BSONObj* recv, int timeoutMs, bool ignoreReturn, bool readOnlyArgs, bool readOnlyRecv) { MozJSEntry entry(this); auto funcValue = _funcs[func - 1]; JS::RootedValue result(_context); const int nargs = argsObject ? argsObject->nFields() : 0; JS::AutoValueVector args(_context); if (nargs) { BSONObjIterator it(*argsObject); for (int i = 0; i < nargs; i++) { BSONElement next = it.next(); JS::RootedValue value(_context); ValueReader(_context, &value).fromBSONElement(next, *argsObject, readOnlyArgs); args.append(value); } } JS::RootedValue smrecv(_context); if (recv) ValueReader(_context, &smrecv).fromBSON(*recv, nullptr, readOnlyRecv); else smrecv.setObjectOrNull(_global); if (timeoutMs) _engine->getDeadlineMonitor().startDeadline(this, timeoutMs); JS::RootedValue out(_context); JS::RootedObject obj(_context, smrecv.toObjectOrNull()); bool success = JS::Call(_context, obj, funcValue, args, &out); if (timeoutMs) _engine->getDeadlineMonitor().stopDeadline(this); _checkErrorState(success); if (!ignoreReturn) { // must validate the handle because TerminateExecution may have // been thrown after the above checks if (out.isObject() && _nativeFunctionProto.instanceOf(out)) { warning() << "storing native function as return value"; _lastRetIsNativeCode = true; } else { _lastRetIsNativeCode = false; } ObjectWrapper(_context, _global).setValue(kInvokeResult, out); } return 0; }
void MozJSImplScope::rename(const char* from, const char* to) { MozJSEntry entry(this); ObjectWrapper(_context, _global).rename(from, to); }
void MozJSImplScope::setBoolean(const char* field, bool val) { MozJSEntry entry(this); ObjectWrapper(_context, _global).setBoolean(field, val); }
BSONObj MozJSImplScope::getObject(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).getObject(field); }
bool MozJSImplScope::getBoolean(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).getBoolean(field); }
std::string MozJSImplScope::getString(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).getString(field); }
void MozJSImplScope::setElement(const char* field, const BSONElement& e, const BSONObj& parent) { MozJSEntry entry(this); ObjectWrapper(_context, _global).setBSONElement(field, e, parent, false); }
void MozJSImplScope::setObject(const char* field, const BSONObj& obj, bool readOnly) { MozJSEntry entry(this); ObjectWrapper(_context, _global).setBSON(field, obj, readOnly); }
long long MozJSImplScope::getNumberLongLong(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).getNumberLongLong(field); }
void DBInfo::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { // 2nd look into real values, may be cached collection object if (!vp.isUndefined()) { auto scope = getScope(cx); auto opContext = scope->getOpContext(); if (opContext && vp.isObject()) { ObjectWrapper o(cx, vp); if (o.hasOwnField(InternedString::_fullName)) { // need to check every time that the collection did not get sharded if (haveLocalShardingInfo(opContext, o.getString(InternedString::_fullName))) uasserted(ErrorCodes::BadValue, "can't use sharded collection from db.eval"); } } return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::JSInterpreterFailure, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); if (parentWrapper.hasOwnField(id)) { parentWrapper.getValue(id, vp); return; } IdWrapper idw(cx, id); // if starts with '_' we dont return collection, one must use getCollection() if (idw.isString()) { JSStringWrapper jsstr; auto sname = idw.toStringData(&jsstr); if (sname.size() == 0 || sname[0] == '_') { return; } } // no hit, create new collection JS::RootedValue getCollection(cx); parentWrapper.getValue(InternedString::getCollection, &getCollection); if (!(getCollection.isObject() && JS_ObjectIsFunction(cx, getCollection.toObjectOrNull()))) { uasserted(ErrorCodes::BadValue, "getCollection is not a function"); } JS::AutoValueArray<1> args(cx); idw.toValue(args[0]); JS::RootedValue coll(cx); ObjectWrapper(cx, obj).callMethod(getCollection, args, &coll); uassert(16861, "getCollection returned something other than a collection", getScope(cx)->getProto<DBCollectionInfo>().instanceOf(coll)); // cache collection for reuse, don't enumerate ObjectWrapper(cx, obj).defineProperty(id, coll, 0); vp.set(coll); }
int MozJSImplScope::type(const char* field) { MozJSEntry entry(this); return ObjectWrapper(_context, _global).type(field); }