| Server IP : 216.92.14.13 / Your IP : 216.73.217.126 Web Server : Apache System : Linux vps4089.pairvps.com 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 User : rmlac2fmr ( 1040637) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/include/mongo/scripting/ |
Upload File : |
/* Copyright 2009 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongo/scripting/engine_spidermonkey.h"
#include <list>
#include <set>
#include <string>
#include <third_party/js-1.7/jsapi.h>
#include <third_party/js-1.7/jsdate.h>
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/jsobj.h"
#define smuassert( cx , msg , val ) \
if ( ! ( val ) ){ \
JS_ReportError( cx , msg ); \
return JS_FALSE; \
}
#define CHECKNEWOBJECT(xx,ctx,w) \
if ( ! xx ){ \
massert(13072,(string)"JS_NewObject failed: " + w ,xx); \
}
#define CHECKJSALLOC( newthing ) \
massert( 13615 , "JS allocation failed, either memory leak or using too much memory" , newthing )
#define smlock boost::recursive_mutex::scoped_lock ___lk( smmutex );
#define GETHOLDER(x,o) ((BSONHolder*)JS_GetPrivate( x , o ))
namespace mongo {
namespace spidermonkey {
using std::string;
typedef std::map<uint32_t, NativeFunction> FunctionMap;
typedef std::map<uint32_t, void*> ArgumentMap;
string trim( string s );
class BSONFieldIterator;
class BSONHolder {
public:
BSONHolder( BSONObj obj ) {
_obj = obj.getOwned();
_inResolve = false;
_modified = false;
_magic = 17;
}
~BSONHolder() {
_magic = 18;
}
void check() {
uassert( 10212 , "holder magic value is wrong" , _magic == 17 && _obj.isValid() );
}
BSONFieldIterator * it();
BSONObj _obj;
bool _inResolve;
char _magic;
std::list<string> _extra;
std::set<string> _removed;
bool _modified;
};
class TraverseStack {
public:
TraverseStack() {
_o = 0;
_parent = 0;
}
TraverseStack( JSObject * o , const TraverseStack * parent ) {
_o = o;
_parent = parent;
}
TraverseStack dive( JSObject * o ) const {
if ( o ) {
uassert( 13076 , (string)"recursive toObject" , ! has( o ) );
}
return TraverseStack( o , this );
}
int depth() const {
int d = 0;
const TraverseStack * s = _parent;
while ( s ) {
s = s->_parent;
d++;
}
return d;
}
bool isTop() const {
return _parent == 0;
}
bool has( JSObject * o ) const {
if ( ! o )
return false;
const TraverseStack * s = this;
while ( s ) {
if ( s->_o == o )
return true;
s = s->_parent;
}
return false;
}
JSObject * _o;
const TraverseStack * _parent;
};
class Convertor : boost::noncopyable {
public:
Convertor( JSContext * cx );
string toString( JSString* jsString );
string toString( jsval v );
// NOTE No validation of passed in object
long long toNumberLongUnsafe( JSObject *o );
int toNumberInt( JSObject *o );
double toNumber( jsval v );
bool toBoolean( jsval v );
OID toOID( jsval v );
BSONObj toObject( JSObject * o , const TraverseStack& stack=TraverseStack() );
BSONObj toObject( jsval v );
string getFunctionCode( JSFunction * func );
string getFunctionCode( jsval v );
void appendRegex( BSONObjBuilder& b , const string& name , string s );
void append( BSONObjBuilder& b,
const std::string& name,
jsval val,
BSONType oldType = EOO,
const TraverseStack& stack=TraverseStack() );
// ---------- to spider monkey ---------
bool hasFunctionIdentifier( const string& code );
bool isSimpleStatement( const string& code );
JSFunction * compileFunction( const char * code, JSObject * assoc = 0 );
JSFunction * _compileFunction( const char * raw , JSObject * assoc , const char *& gcName );
jsval toval( double d );
jsval toval( const char * c );
JSObject * toJSObject( const BSONObj * obj , bool readOnly=false );
jsval toval( const BSONObj* obj , bool readOnly=false );
void makeLongObj( long long n, JSObject * o );
jsval toval( long long n );
void makeIntObj( int n, JSObject * o );
jsval toval( int n );
jsval toval( const BSONElement& e );
// ------- object helpers ------
JSObject * getJSObject( JSObject * o , const char * name );
JSObject * getGlobalObject( const char * name );
JSObject * getGlobalPrototype( const char * name );
bool hasProperty( JSObject * o , const char * name );
jsval getProperty( JSObject * o , const char * field );
void setProperty( JSObject * o , const char * field , jsval v );
string typeString( jsval v );
bool getBoolean( JSObject * o , const char * field );
double getNumber( JSObject * o , const char * field );
string getString( JSObject * o , const char * field );
JSClass * getClass( JSObject * o , const char * field );
JSContext * _context;
};
class SMScope : public Scope {
public:
SMScope();
~SMScope();
void reset();
void init( const BSONObj * data );
bool hasOutOfMemoryException();
void externalSetup();
/** check if there is a pending killOp request */
bool isKillPending() const;
void localConnect( const char * dbName );
// ----- getters ------
double getNumber( const char *field );
string getString( const char *field );
bool getBoolean( const char *field );
BSONObj getObject( const char *field );
JSObject * getJSObject( const char * field );
int type( const char *field );
// ----- setters ------
void setElement( const char *field , const BSONElement& val );
void setNumber( const char *field , double val );
void setString( const char *field , const char * val );
void setObject( const char *field , const BSONObj& obj , bool readOnly );
void setBoolean( const char *field , bool val );
void setThis( const BSONObj * obj );
void setFunction( const char *field , const char * code );
void rename( const char * from , const char * to );
// ---- functions -----
ScriptingFunction _createFunction(const char* code, ScriptingFunction functionNumber);
struct TimeoutSpec {
boost::posix_time::ptime start;
boost::posix_time::time_duration timeout;
int count;
};
// should not generate exceptions, as those can be caught in
// javascript code; returning false without an exception exits
// immediately
static JSBool _interrupt( JSContext *cx );
static JSBool interrupt( JSContext *cx, JSScript *script ) {
return _interrupt( cx );
}
void installInterrupt( int timeoutMs );
void uninstallInterrupt( int timeoutMs );
void precall();
bool isReportingErrors() const { return _reportError; }
bool exec( const StringData& code,
const string& name = "(anon)",
bool printResult = false,
bool reportError = true,
bool assertOnError = true,
int timeoutMs = 0 );
int invoke( JSFunction* func,
const BSONObj* args,
const BSONObj* recv,
int timeoutMs,
bool ignoreReturn,
bool readOnlyArgs,
bool readOnlyRecv );
int invoke( ScriptingFunction funcAddr,
const BSONObj* args,
const BSONObj* recv,
int timeoutMs = 0,
bool ignoreReturn = 0,
bool readOnlyArgs = false,
bool readOnlyRecv = false ) {
return invoke( reinterpret_cast<JSFunction*>( funcAddr ),
args,
recv,
timeoutMs,
ignoreReturn,
readOnlyArgs,
readOnlyRecv );
}
void gotError( const std::string& s ) {
_error = s;
}
string getError() {
return _error;
}
void injectNative( const char *field, NativeFunction func, void* data );
virtual void gc();
JSContext *SavedContext() const { return _context; }
// map from internal function id to function pointer
FunctionMap _functionMap;
// map from internal function argument id to function pointer
ArgumentMap _argumentMap;
private:
void _postCreateHacks();
JSContext * _context;
Convertor * _convertor;
JSObject * _global;
JSObject * _this;
string _error;
bool _reportError;
bool _externalSetup;
bool _localConnect;
set<string> _initFieldNames;
};
/**
* Get the connection object associated with "cx" and "obj".
*/
DBClientWithCommands *getConnection(JSContext *cx, JSObject *obj);
/**
* Register a function that should be part of the Mongo object in the javascript shell.
*
* This function may only be called from MONGO_INITIALIZERs with SmMongoFunctionsRegistry as
* a prerequisite, and SmMongoFunctionRegistrationDone as a dependent.
*/
void registerMongoFunction(const JSFunctionSpec& functionSpec);
} // namespace spidermonkey
} // namespace mongo