diff options
Diffstat (limited to 'community/mongodb/mongodb-1.8.0-spidermonkey-1.8.5-support.patch')
-rw-r--r-- | community/mongodb/mongodb-1.8.0-spidermonkey-1.8.5-support.patch | 1502 |
1 files changed, 1502 insertions, 0 deletions
diff --git a/community/mongodb/mongodb-1.8.0-spidermonkey-1.8.5-support.patch b/community/mongodb/mongodb-1.8.0-spidermonkey-1.8.5-support.patch new file mode 100644 index 000000000..46160450f --- /dev/null +++ b/community/mongodb/mongodb-1.8.0-spidermonkey-1.8.5-support.patch @@ -0,0 +1,1502 @@ +--- mongodb-src-r1.8.0/SConstruct.mozjs185~ 2011-03-16 16:33:30.000000000 +0100 ++++ mongodb-src-r1.8.0/SConstruct 2011-04-01 22:16:43.411100876 +0200 +@@ -671,7 +671,6 @@ if nix: + env.Append( CPPFLAGS="-fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch" ) + # env.Append( " -Wconversion" ) TODO: this doesn't really work yet + if linux: +- env.Append( CPPFLAGS=" -Werror " ) + env.Append( CPPFLAGS=" -fno-builtin-memcmp " ) # glibc's memcmp is faster than gcc's + env.Append( CXXFLAGS=" -Wnon-virtual-dtor " ) + env.Append( LINKFLAGS=" -fPIC -pthread -rdynamic" ) +@@ -893,11 +892,11 @@ def doConfigure( myenv , needPcre=True , + if usesm: + + # see http://www.mongodb.org/pages/viewpageattachments.action?pageId=12157032 +- J = [ "mozjs" , "js", "js_static" ] ++ J = [ "mozjs185" , "js", "js_static" ] + if windows: + if msarch == "amd64": + if release: +- J = [ "js64r", "js", "mozjs" , "js_static" ] ++ J = [ "js64r", "js", "mozjs185" , "js_static" ] + else: + J = "js64d" + print( "looking for js64d.lib for spidermonkey. (available at mongodb.org prebuilt)" ); +@@ -905,14 +904,12 @@ def doConfigure( myenv , needPcre=True , + if not force32: + print( "Assuming a 32 bit build is desired" ) + if release: +- J = [ "js32r", "js", "mozjs" , "js_static" ] ++ J = [ "js32r", "js", "mozjs185" , "js_static" ] + else: +- J = [ "js32d", "js", "mozjs" , "js_static" ] ++ J = [ "js32d", "js", "mozjs185" , "js_static" ] + + myCheckLib( J , True ) + mozHeader = "js" +- if bigLibString(myenv).find( "mozjs" ) >= 0: +- mozHeader = "mozjs" + + if not conf.CheckHeader( mozHeader + "/jsapi.h" ): + if conf.CheckHeader( "jsapi.h" ): +@@ -921,6 +918,13 @@ def doConfigure( myenv , needPcre=True , + print( "no spider monkey headers!" ) + Exit(1) + ++ if conf.CheckFunc( 'JS_NewCompartmentAndGlobalObject' ): ++ myenv.Append( CPPDEFINES=[ "HAVE_COMPARTMENTS" ] ) ++ if conf.CheckFunc( 'JS_GetStringCharsAndLength' ): ++ myenv.Append( CPPDEFINES=[ "HAVE_JS_GET_STRING_CHARS_AND_LENGTH" ] ) ++ if conf.CheckFunc( 'JS_NewRegExpObjectNoStatics' ): ++ myenv.Append( CPPDEFINES=[ "JS_NEW_REG_EXP_OBJECT_NO_STATISTICS" ] ) ++ + if usev8: + if debugBuild: + myCheckLib( [ "v8_g" , "v8" ] , True ) +--- mongodb-src-r1.8.0/scripting/engine_spidermonkey.cpp.mozjs185~ 2011-03-16 16:33:30.000000000 +0100 ++++ mongodb-src-r1.8.0/scripting/engine_spidermonkey.cpp 2011-04-01 22:42:19.780233492 +0200 +@@ -192,8 +192,13 @@ namespace mongo { + } + + string toString( JSString * so ) { ++#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH ++ size_t srclen; ++ const jschar * s = JS_GetStringCharsAndLength( _context , so , &srclen ); ++#else + jschar * s = JS_GetStringChars( so ); + size_t srclen = JS_GetStringLength( so ); ++#endif + if( srclen == 0 ) + return ""; + +@@ -360,7 +365,7 @@ namespace mongo { + + case JSTYPE_OBJECT: { + JSObject * o = JSVAL_TO_OBJECT( val ); +- if ( ! o || o == JSVAL_NULL ) { ++ if ( ! o || o == (JSObject *)JSVAL_NULL ){ + b.appendNull( name ); + } + else if ( ! appendSpecialDBObject( this , b , name , val , o ) ) { +@@ -419,16 +424,15 @@ namespace mongo { + return true; + } + +- void addRoot( JSFunction * f , const char * name ); ++ void addRoot( JSFunction * f ); + + JSFunction * compileFunction( const char * code, JSObject * assoc = 0 ) { +- const char * gcName = "unknown"; +- JSFunction * f = _compileFunction( code , assoc , gcName ); +- //addRoot( f , gcName ); ++ JSFunction * f = _compileFunction( code , assoc ); ++ //addRoot( f ); + return f; + } + +- JSFunction * _compileFunction( const char * raw , JSObject * assoc , const char *& gcName ) { ++ JSFunction * _compileFunction( const char * raw , JSObject * assoc ) { + if ( ! assoc ) + assoc = JS_GetGlobalObject( _context ); + +@@ -447,7 +451,6 @@ namespace mongo { + if ( isSimpleStatement( s ) ) { + s = "return " + s; + } +- gcName = "cf anon"; + fname << "anon"; + return JS_CompileFunction( _context , assoc , fname.str().c_str() , 0 , 0 , s.c_str() , s.size() , "nofile_a" , 0 ); + } +@@ -488,7 +491,6 @@ namespace mongo { + log() << "compile failed for: " << raw << endl; + return 0; + } +- gcName = "cf normal"; + return func; + } + +@@ -630,7 +632,11 @@ namespace mongo { + flags++; + } + ++#ifdef JS_NEW_REG_EXP_OBJECT_NO_STATISTICS ++ JSObject * r = JS_NewRegExpObjectNoStatics( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber); ++#else + JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber ); ++#endif + assert( r ); + return OBJECT_TO_JSVAL( r ); + } +@@ -791,7 +797,7 @@ namespace mongo { + + BSONFieldIterator * it = (BSONFieldIterator*)JSVAL_TO_PRIVATE( *statep ); + if ( ! it ) { +- *statep = 0; ++ *statep = JSVAL_NULL; + return JS_TRUE; + } + +@@ -803,7 +809,7 @@ namespace mongo { + } + else { + delete it; +- *statep = 0; ++ *statep = JSVAL_NULL; + } + return JS_TRUE; + } +@@ -818,7 +824,7 @@ namespace mongo { + return JS_FALSE; + } + +- JSBool noaccess( JSContext *cx, JSObject *obj, jsval idval, jsval *vp) { ++ JSBool noaccess( JSContext *cx, JSObject *obj, jsid id, jsval *vp){ + BSONHolder * holder = GETHOLDER( cx , obj ); + if ( ! holder ) { + // in init code still +@@ -830,24 +836,37 @@ namespace mongo { + return JS_FALSE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) ++ JSBool strict_noaccess( JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp){ ++ return noaccess( cx , obj , id , vp ); ++ } ++ ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp, JSResolveOp) + JSClass bson_ro_class = { + "bson_ro_object" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE , +- noaccess, noaccess, JS_PropertyStub, noaccess, +- (JSEnumerateOp)bson_enumerate, (JSResolveOp)(&resolveBSONField) , JS_ConvertStub, bson_finalize , ++ noaccess, noaccess, JS_PropertyStub, strict_noaccess, ++ (JSEnumerateOp)bson_enumerate, (JSResolveOp)resolveBSONField , JS_ConvertStub, bson_finalize , + JSCLASS_NO_OPTIONAL_MEMBERS + }; + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool bson_cons( JSContext* cx, uintN argc, jsval* vp ){ ++#else + JSBool bson_cons( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + cerr << "bson_cons : shouldn't be here!" << endl; + JS_ReportError( cx , "can't construct bson object" ); + return JS_FALSE; + } + + JSFunctionSpec bson_functions[] = { +- { 0 } ++ JS_FS_END + }; + +- JSBool bson_add_prop( JSContext *cx, JSObject *obj, jsval idval, jsval *vp) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSPropertyOp) ++ JSBool bson_add_prop( JSContext *cx, JSObject *obj, jsid id, jsval *vp){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + BSONHolder * holder = GETHOLDER( cx , obj ); + if ( ! holder ) { + // static init +@@ -864,8 +883,10 @@ namespace mongo { + return JS_TRUE; + } + +- +- JSBool mark_modified( JSContext *cx, JSObject *obj, jsval idval, jsval *vp) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSPropertyOp) ++ JSBool mark_modified( JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + Convertor c(cx); + BSONHolder * holder = GETHOLDER( cx , obj ); + if ( !holder ) // needed when we're messing with DBRef.prototype +@@ -877,7 +898,10 @@ namespace mongo { + return JS_TRUE; + } + +- JSBool mark_modified_remove( JSContext *cx, JSObject *obj, jsval idval, jsval *vp) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSPropertyOp) ++ JSBool mark_modified_remove( JSContext *cx, JSObject *obj, jsid id, jsval *vp){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + Convertor c(cx); + BSONHolder * holder = GETHOLDER( cx , obj ); + if ( holder->_inResolve ) +@@ -887,23 +911,26 @@ namespace mongo { + return JS_TRUE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp, JSResolveOp) + JSClass bson_class = { + "bson_object" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE , + bson_add_prop, mark_modified_remove, JS_PropertyStub, mark_modified, +- (JSEnumerateOp)bson_enumerate, (JSResolveOp)(&resolveBSONField) , JS_ConvertStub, bson_finalize , ++ (JSEnumerateOp)bson_enumerate, (JSResolveOp)resolveBSONField , JS_ConvertStub, bson_finalize , + JSCLASS_NO_OPTIONAL_MEMBERS + }; + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + static JSClass global_class = { + "global", JSCLASS_GLOBAL_FLAGS, +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + // --- global helpers --- + +- JSBool native_print( JSContext * cx , JSObject * obj , uintN argc, jsval *argv, jsval *rval ) { ++ JSBool native_print( JSContext * cx , uintN argc , jsval *vp ){ ++ jsval *argv = JS_ARGV( cx , vp); + stringstream ss; + Convertor c( cx ); + for ( uintN i=0; i<argc; i++ ) { +@@ -913,10 +940,13 @@ namespace mongo { + } + ss << "\n"; + Logstream::logLockless( ss.str() ); ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + return JS_TRUE; + } + +- JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) { ++ JSBool native_helper( JSContext *cx , uintN argc, jsval *vp){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + + NativeFunction func = (NativeFunction)((long long)c.getNumber( obj , "x" ) ); +@@ -942,35 +972,37 @@ namespace mongo { + } + + if ( out.isEmpty() ) { +- *rval = JSVAL_VOID; ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + } + else { +- *rval = c.toval( out.firstElement() ); ++ JS_SET_RVAL( cx , vp , c.toval( out.firstElement() ) ); + } + + return JS_TRUE; + } + +- JSBool native_load( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ); ++ JSBool native_load( JSContext *cx , uintN argc, jsval *vp ); + +- JSBool native_gc( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) { ++ JSBool native_gc( JSContext *cx , uintN argc, jsval *vp ){ + JS_GC( cx ); ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + return JS_TRUE; + } + + JSFunctionSpec globalHelpers[] = { +- { "print" , &native_print , 0 , 0 , 0 } , +- { "nativeHelper" , &native_helper , 1 , 0 , 0 } , +- { "load" , &native_load , 1 , 0 , 0 } , +- { "gc" , &native_gc , 1 , 0 , 0 } , +- { 0 , 0 , 0 , 0 , 0 } ++ JS_FS( "print" , &native_print , 0 , JSFUN_FAST_NATIVE ) , ++ JS_FS( "nativeHelper" , &native_helper , 1 , JSFUN_FAST_NATIVE ) , ++ JS_FS( "load" , &native_load , 1 , JSFUN_FAST_NATIVE ) , ++ JS_FS( "gc" , &native_gc , 1 , JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // ----END global helpers ---- + + // Object helpers + +- JSBool bson_get_size(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bson_get_size(JSContext *cx, uintN argc, jsval *vp){ ++ jsval *argv = JS_ARGV( cx , vp ); + if ( argc != 1 || !JSVAL_IS_OBJECT( argv[ 0 ] ) ) { + JS_ReportError( cx , "bsonsize requires one valid object" ); + return JS_FALSE; +@@ -979,7 +1011,7 @@ namespace mongo { + Convertor c(cx); + + if ( argv[0] == JSVAL_VOID || argv[0] == JSVAL_NULL ) { +- *rval = c.toval( 0.0 ); ++ JS_SET_RVAL( cx , vp , c.toval( 0.0 ) ); + return JS_TRUE; + } + +@@ -999,18 +1031,21 @@ namespace mongo { + size = temp.objsize(); + } + +- *rval = c.toval( size ); ++ JS_SET_RVAL( cx , vp , c.toval( size ) ); + return JS_TRUE; + } + + JSFunctionSpec objectHelpers[] = { +- { "bsonsize" , &bson_get_size , 1 , 0 , 0 } , +- { 0 , 0 , 0 , 0 , 0 } ++ JS_FS( "bsonsize" , &bson_get_size , 1 , JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // end Object helpers + +- JSBool resolveBSONField( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSResolveOp) ++ JSBool resolveBSONField( JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp ){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + assert( JS_EnterLocalRootScope( cx ) ); + Convertor c( cx ); + +@@ -1023,7 +1058,7 @@ namespace mongo { + } + holder->check(); + +- string s = c.toString( id ); ++ string s = c.toString( idval ); + + BSONElement e = holder->_obj[ s.c_str() ]; + +@@ -1139,9 +1174,15 @@ namespace mongo { + //JS_SetVersion( _context , JSVERSION_LATEST); TODO + JS_SetErrorReporter( _context , errorReporter ); + ++#ifdef HAVE_COMPARTMENTS ++ _global = JS_NewCompartmentAndGlobalObject( _context , &global_class , NULL); ++ massert( 13442 , "JS_NewCompartmentAndGlobalObject failed for global" , _global ); ++ _call = JS_EnterCrossCompartmentCall( _context , _global); ++#else + _global = JS_NewObject( _context , &global_class, NULL, NULL); + massert( 10432 , "JS_NewObject failed for global" , _global ); + JS_SetGlobalObject( _context , _global ); ++#endif + massert( 10433 , "js init failed" , JS_InitStandardClasses( _context , _global ) ); + + JS_SetOptions( _context , JS_GetOptions( _context ) | JSOPTION_VAROBJFIX ); +@@ -1159,13 +1200,14 @@ namespace mongo { + smlock; + uassert( 10223 , "deleted SMScope twice?" , _convertor ); + +- for ( list<void*>::iterator i=_roots.begin(); i != _roots.end(); i++ ) { +- JS_RemoveRoot( _context , *i ); ++ for ( list<JSObject*>::iterator i=_roots.begin(); i != _roots.end(); i++ ){ ++ JSObject * obj = (JSObject *)*i; ++ JS_RemoveObjectRoot( _context , &obj ); + } + _roots.clear(); + + if ( _this ) { +- JS_RemoveRoot( _context , &_this ); ++ JS_RemoveObjectRoot( _context , &_this ); + _this = 0; + } + +@@ -1174,6 +1216,13 @@ namespace mongo { + _convertor = 0; + } + ++#ifdef HAVE_COMPARTMENTS ++ if ( _call ) { ++ JS_LeaveCrossCompartmentCall( _call ); ++ _call = 0; ++ } ++#endif ++ + if ( _context ) { + // This is expected to reclaim _global as well. + JS_DestroyContext( _context ); +@@ -1187,16 +1236,16 @@ namespace mongo { + assert( _convertor ); + return; + if ( _this ) { +- JS_RemoveRoot( _context , &_this ); ++ JS_RemoveObjectRoot( _context , &_this ); + _this = 0; + } + currentScope.reset( this ); + _error = ""; + } + +- void addRoot( void * root , const char * name ) { +- JS_AddNamedRoot( _context , root , name ); +- _roots.push_back( root ); ++ void addRoot( JSObject * obj ){ ++ JS_AddObjectRoot( _context , &obj ); ++ _roots.push_back( obj ); + } + + void init( const BSONObj * data ) { +@@ -1336,13 +1385,13 @@ namespace mongo { + void setThis( const BSONObj * obj ) { + smlock; + if ( _this ) { +- JS_RemoveRoot( _context , &_this ); ++ JS_RemoveObjectRoot( _context , &_this ); + _this = 0; + } + + if ( obj ) { + _this = _convertor->toJSObject( obj ); +- JS_AddNamedRoot( _context , &_this , "scope this" ); ++ JS_AddObjectRoot( _context , &_this ); + } + } + +@@ -1402,7 +1451,7 @@ namespace mongo { + spec->start = boost::posix_time::microsec_clock::local_time(); + spec->count = 0; + JS_SetContextPrivate( _context, (void*)spec ); +-#if defined(SM181) && !defined(XULRUNNER190) ++#if JS_VERSION >= 181 && !defined(XULRUNNER190) + JS_SetOperationCallback( _context, _interrupt ); + #else + JS_SetBranchCallback( _context, interrupt ); +@@ -1412,7 +1461,7 @@ namespace mongo { + + void uninstallInterrupt( int timeoutMs ) { + if ( timeoutMs != 0 || ScriptEngine::haveCheckInterruptCallback() ) { +-#if defined(SM181) && !defined(XULRUNNER190) ++#if JS_VERSION >= 181 && !defined(XULRUNNER190) + JS_SetOperationCallback( _context , 0 ); + #else + JS_SetBranchCallback( _context, 0 ); +@@ -1548,9 +1597,12 @@ namespace mongo { + + JSObject * _global; + JSObject * _this; ++#ifdef HAVE_COMPARTMENTS ++ JSCrossCompartmentCall * _call; ++#endif + + string _error; +- list<void*> _roots; ++ list<JSObject*> _roots; + + bool _externalSetup; + bool _localConnect; +@@ -1579,7 +1631,8 @@ namespace mongo { + } + } + +- JSBool native_load( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) { ++ JSBool native_load( JSContext *cx , uintN argc, jsval *vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); + Convertor c(cx); + + Scope * s = currentScope.get(); +@@ -1594,6 +1647,7 @@ namespace mongo { + } + } + ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + return JS_TRUE; + } + +@@ -1633,7 +1687,7 @@ namespace mongo { + return new SMScope(); + } + +- void Convertor::addRoot( JSFunction * f , const char * name ) { ++ void Convertor::addRoot( JSFunction * f ){ + if ( ! f ) + return; + +@@ -1642,7 +1696,7 @@ namespace mongo { + + JSObject * o = JS_GetFunctionObject( f ); + assert( o ); +- scope->addRoot( &o , name ); ++ scope->addRoot( o ); + } + + } +--- mongodb-src-r1.8.0/scripting/engine_spidermonkey.h.mozjs185~ 2011-03-16 16:33:30.000000000 +0100 ++++ mongodb-src-r1.8.0/scripting/engine_spidermonkey.h 2011-04-01 21:29:15.697678508 +0200 +@@ -21,6 +21,9 @@ + + // START inc hacking + ++#undef malloc ++#undef realloc ++ + #if defined( MOZJS ) + + #define MOZILLA_1_8_BRANCH +@@ -55,6 +58,9 @@ + + #endif + ++#define malloc MONGO_malloc ++#define realloc MONGO_realloc ++ + // END inc hacking + + // -- SM 1.6 hacks --- +@@ -81,6 +87,10 @@ JSBool JS_CStringsAreUTF8() { + #define SM181 + #endif + ++#ifndef JSFUN_FAST_NATIVE ++#define JSFUN_FAST_NATIVE 0 ++#endif ++ + namespace mongo { + + class SMScope; +@@ -104,7 +114,7 @@ namespace mongo { + extern boost::thread_specific_ptr<SMScope> currentScope; + + // bson +- JSBool resolveBSONField( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ); ++ JSBool resolveBSONField( JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp ); + + + // mongo +--- mongodb-src-r1.8.0/scripting/sm_db.cpp.mozjs185~ 2011-03-16 16:33:30.000000000 +0100 ++++ mongodb-src-r1.8.0/scripting/sm_db.cpp 2011-04-01 22:51:59.701652521 +0200 +@@ -79,13 +79,25 @@ namespace mongo { + return holder->get(); + } + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool internal_cursor_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool internal_cursor_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + uassert( 10236 , "no args to internal_cursor_constructor" , argc == 0 ); + assert( JS_SetPrivate( cx , obj , 0 ) ); // just for safety ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + +- void internal_cursor_finalize( JSContext * cx , JSObject * obj ) { ++ void internal_cursor_finalize( JSContext * cx, JSObject * obj ){ + CursorHolder * holder = (CursorHolder*)JS_GetPrivate( cx , obj ); + if ( holder ) { + delete holder; +@@ -93,10 +105,11 @@ namespace mongo { + } + } + +- JSBool internal_cursor_hasNext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool internal_cursor_hasNext(JSContext *cx , uintN argc , jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); + DBClientCursor *cursor = getCursor( cx, obj ); + try { +- *rval = cursor->more() ? JSVAL_TRUE : JSVAL_FALSE; ++ JS_SET_RVAL( cx , vp , cursor->more() ? JSVAL_TRUE : JSVAL_FALSE ); + } + catch ( std::exception& e ) { + JS_ReportError( cx , e.what() ); +@@ -105,14 +118,16 @@ namespace mongo { + return JS_TRUE; + } + +- JSBool internal_cursor_objsLeftInBatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool internal_cursor_objsLeftInBatch(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); + DBClientCursor *cursor = getCursor( cx, obj ); + Convertor c(cx); +- *rval = c.toval((double) cursor->objsLeftInBatch() ); ++ JS_SET_RVAL( cx , vp , c.toval((double) cursor->objsLeftInBatch()) ); + return JS_TRUE; + } + +- JSBool internal_cursor_next(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool internal_cursor_next(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); + DBClientCursor *cursor = getCursor( cx, obj ); + + BSONObj n; +@@ -131,20 +146,21 @@ namespace mongo { + } + + Convertor c(cx); +- *rval = c.toval( &n ); ++ JS_SET_RVAL( cx , vp , c.toval( &n ) ); + return JS_TRUE; + } + + JSFunctionSpec internal_cursor_functions[] = { +- { "hasNext" , internal_cursor_hasNext , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "objsLeftInBatch" , internal_cursor_objsLeftInBatch , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "next" , internal_cursor_next , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "hasNext" , internal_cursor_hasNext , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "objsLeftInBatch" , internal_cursor_objsLeftInBatch , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "next" , internal_cursor_next , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass internal_cursor_class = { + "InternalCursor" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, internal_cursor_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS + }; +@@ -157,7 +173,16 @@ namespace mongo { + throw -1; + } + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool mongo_local_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool mongo_local_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + shared_ptr< DBClientWithCommands > client( createDirectClient() ); +@@ -166,10 +191,23 @@ namespace mongo { + jsval host = c.toval( "EMBEDDED" ); + assert( JS_SetProperty( cx , obj , "host" , &host ) ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool mongo_external_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool mongo_external_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + smuassert( cx , "0 or 1 args to Mongo" , argc <= 1 ); +@@ -197,6 +235,9 @@ namespace mongo { + assert( JS_SetPrivate( cx , obj , (void*)( new shared_ptr< DBClientWithCommands >( conn ) ) ) ); + jsval host_val = c.toval( host.c_str() ); + assert( JS_SetProperty( cx , obj , "host" , &host_val ) ); ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + + } +@@ -215,14 +256,18 @@ namespace mongo { + } + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass mongo_class = { + "Mongo" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, mongo_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + +- JSBool mongo_find(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool mongo_find(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); ++ jsval* argv = JS_ARGV( cx , vp ); ++ + smuassert( cx , "mongo_find needs 7 args" , argc == 7 ); + shared_ptr< DBClientWithCommands > * connHolder = (shared_ptr< DBClientWithCommands >*)JS_GetPrivate( cx , obj ); + smuassert( cx , "no connection!" , connHolder && connHolder->get() ); +@@ -252,7 +297,8 @@ namespace mongo { + JSObject * mycursor = JS_NewObject( cx , &internal_cursor_class , 0 , 0 ); + CHECKNEWOBJECT( mycursor, cx, "internal_cursor_class" ); + assert( JS_SetPrivate( cx , mycursor , new CursorHolder( cursor, *connHolder ) ) ); +- *rval = OBJECT_TO_JSVAL( mycursor ); ++ ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( mycursor )); + return JS_TRUE; + } + catch ( ... ) { +@@ -261,7 +307,10 @@ namespace mongo { + } + } + +- JSBool mongo_update(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool mongo_update(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); ++ jsval* argv = JS_ARGV( cx , vp ); ++ + smuassert( cx , "mongo_find needs at elast 3 args" , argc >= 3 ); + smuassert( cx , "2nd param to update has to be an object" , JSVAL_IS_OBJECT( argv[1] ) ); + smuassert( cx , "3rd param to update has to be an object" , JSVAL_IS_OBJECT( argv[2] ) ); +@@ -282,6 +331,7 @@ namespace mongo { + + try { + conn->update( ns , c.toObject( argv[1] ) , c.toObject( argv[2] ) , upsert , multi ); ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + return JS_TRUE; + } + catch ( ... ) { +@@ -290,7 +340,10 @@ namespace mongo { + } + } + +- JSBool mongo_insert(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool mongo_insert(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); ++ jsval* argv = JS_ARGV( cx , vp ); ++ + smuassert( cx , "mongo_insert needs 2 args" , argc == 2 ); + smuassert( cx , "2nd param to insert has to be an object" , JSVAL_IS_OBJECT( argv[1] ) ); + +@@ -310,6 +363,7 @@ namespace mongo { + // TODO: add _id + + conn->insert( ns , o ); ++ JS_SET_RVAL( cx, vp, JSVAL_VOID ); + return JS_TRUE; + } + catch ( std::exception& e ) { +@@ -325,7 +379,10 @@ namespace mongo { + } + } + +- JSBool mongo_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool mongo_remove(JSContext *cx, uintN argc, jsval *vp) { ++ JSObject* obj = JS_THIS_OBJECT( cx , vp ); ++ jsval* argv = JS_ARGV( cx , vp ); ++ + smuassert( cx , "mongo_remove needs 2 or 3 arguments" , argc == 2 || argc == 3 ); + smuassert( cx , "2nd param to insert has to be an object" , JSVAL_IS_OBJECT( argv[1] ) ); + +@@ -346,6 +403,7 @@ namespace mongo { + + try { + conn->remove( ns , o , justOne ); ++ JS_SET_RVAL( cx , vp , JSVAL_VOID ); + return JS_TRUE; + } + catch ( std::exception& e ) { +@@ -361,16 +419,26 @@ namespace mongo { + } + + JSFunctionSpec mongo_functions[] = { +- { "find" , mongo_find , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "update" , mongo_update , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "insert" , mongo_insert , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "remove" , mongo_remove , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "find" , mongo_find , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "update" , mongo_update , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "insert" , mongo_insert , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "remove" , mongo_remove , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // ------------- db_collection ------------- + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool db_collection_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool db_collection_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + smuassert( cx , "db_collection_constructor wrong args" , argc == 4 ); + assert( JS_SetProperty( cx , obj , "_mongo" , &(argv[0]) ) ); + assert( JS_SetProperty( cx , obj , "_db" , &(argv[1]) ) ); +@@ -382,16 +450,22 @@ namespace mongo { + JS_ReportError( cx , "can't use sharded collection from db.eval" ); + return JS_FALSE; + } +- ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + +- JSBool db_collection_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSResolveOp) ++ JSBool db_collection_resolve( JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp ){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); ++ + if ( flags & JSRESOLVE_ASSIGNING ) + return JS_TRUE; + + Convertor c( cx ); +- string collname = c.toString( id ); ++ string collname = c.toString( idval ); + + if ( isSpecialName( collname ) ) + return JS_TRUE; +@@ -419,10 +493,11 @@ namespace mongo { + return JS_TRUE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp, JSResolveOp) + JSClass db_collection_class = { + "DBCollection" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, +- JS_EnumerateStub, (JSResolveOp)(&db_collection_resolve) , JS_ConvertStub, JS_FinalizeStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, ++ JS_EnumerateStub, (JSResolveOp)db_collection_resolve , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + +@@ -454,15 +529,32 @@ namespace mongo { + // -------------- DB --------------- + + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool db_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool db_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + smuassert( cx, "wrong number of arguments to DB" , argc == 2 ); + assert( JS_SetProperty( cx , obj , "_mongo" , &(argv[0]) ) ); + assert( JS_SetProperty( cx , obj , "_name" , &(argv[1]) ) ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif ++ + return JS_TRUE; + } + +- JSBool db_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSResolveOp) ++ JSBool db_resolve( JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp ){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + if ( flags & JSRESOLVE_ASSIGNING ) + return JS_TRUE; + +@@ -471,7 +563,7 @@ namespace mongo { + if ( obj == c.getGlobalPrototype( "DB" ) ) + return JS_TRUE; + +- string collname = c.toString( id ); ++ string collname = c.toString( idval ); + + if ( isSpecialName( collname ) ) + return JS_TRUE; +@@ -489,17 +581,28 @@ namespace mongo { + return JS_TRUE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp, JSResolveOp) + JSClass db_class = { + "DB" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, +- JS_EnumerateStub, (JSResolveOp)(&db_resolve) , JS_ConvertStub, JS_FinalizeStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, ++ JS_EnumerateStub, (JSResolveOp)db_resolve , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + + // -------------- object id ------------- + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool object_id_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool object_id_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + OID oid; +@@ -524,35 +627,48 @@ namespace mongo { + if ( ! JS_InstanceOf( cx , obj , &object_id_class , 0 ) ) { + obj = JS_NewObject( cx , &object_id_class , 0 , 0 ); + CHECKNEWOBJECT( obj, cx, "object_id_constructor" ); +- *rval = OBJECT_TO_JSVAL( obj ); + } + + jsval v = c.toval( oid.str().c_str() ); + assert( JS_SetProperty( cx , obj , "str" , &v ) ); + ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); + return JS_TRUE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass object_id_class = { + "ObjectId" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + +- JSBool object_id_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool object_id_tostring(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); +- return (JSBool) (*rval = c.getProperty( obj , "str" )); ++ JS_SET_RVAL( cx , vp , c.getProperty( obj , "str" )); ++ return JS_TRUE; + } + + JSFunctionSpec object_id_functions[] = { +- { "toString" , object_id_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "toString" , object_id_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // dbpointer + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool dbpointer_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool dbpointer_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + if ( argc == 2 ) { +@@ -564,6 +680,9 @@ namespace mongo { + + assert( JS_SetProperty( cx , obj , "ns" , &(argv[0]) ) ); + assert( JS_SetProperty( cx , obj , "id" , &(argv[1]) ) ); ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + else { +@@ -572,19 +691,30 @@ namespace mongo { + } + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass dbpointer_class = { + "DBPointer" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSFunctionSpec dbpointer_functions[] = { +- { 0 } ++ JS_FS_END + }; + + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool dbref_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool dbref_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + if ( argc == 2 ) { +@@ -594,6 +724,9 @@ namespace mongo { + assert( JS_SetProperty( cx, o , "$id" , &argv[ 1 ] ) ); + BSONObj bo = c.toObject( o ); + assert( JS_SetPrivate( cx , obj , (void*)(new BSONHolder( bo.getOwned() ) ) ) ); ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + else { +@@ -607,7 +740,17 @@ namespace mongo { + + // UUID ************************** + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool uuid_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool uuid_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + if( argc == 0 ) { +@@ -635,6 +778,9 @@ namespace mongo { + c.setProperty( obj, "len", c.toval( (double)16 ) ); + c.setProperty( obj, "type", c.toval( (double)3 ) ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + else { +@@ -643,7 +789,8 @@ namespace mongo { + } + } + +- JSBool uuid_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool uuid_tostring(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + void *holder = JS_GetPrivate( cx, obj ); + assert( holder ); +@@ -652,7 +799,8 @@ namespace mongo { + ss << "UUID(\"" << toHex(data, 16); + ss << "\")"; + string ret = ss.str(); +- return *rval = c.toval( ret.c_str() ); ++ JS_SET_RVAL( cx , vp , c.toval( ret.c_str() ) ); ++ return JS_TRUE; + } + + void uuid_finalize( JSContext * cx , JSObject * obj ) { +@@ -664,21 +812,32 @@ namespace mongo { + } + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass uuid_class = { + "UUID" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, uuid_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSFunctionSpec uuid_functions[] = { +- { "toString" , uuid_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "toString" , uuid_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // BinData ************************** + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool bindata_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool bindata_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + Convertor c( cx ); + + if ( argc == 2 ) { +@@ -702,6 +861,9 @@ namespace mongo { + c.setProperty( obj, "len", c.toval( (double)decoded.length() ) ); + c.setProperty( obj, "type", c.toval( (double)type ) ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + else { +@@ -710,7 +872,8 @@ namespace mongo { + } + } + +- JSBool bindata_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bindata_tostring(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + int type = (int)c.getNumber( obj , "type" ); + int len = (int)c.getNumber( obj, "len" ); +@@ -722,10 +885,12 @@ namespace mongo { + base64::encode( ss, (const char *)data, len ); + ss << "\")"; + string ret = ss.str(); +- return *rval = c.toval( ret.c_str() ); ++ JS_SET_RVAL( cx , vp , c.toval( ret.c_str() ) ); ++ return JS_TRUE; + } + +- JSBool bindataBase64(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bindataBase64(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + int len = (int)c.getNumber( obj, "len" ); + void *holder = JS_GetPrivate( cx, obj ); +@@ -734,10 +899,12 @@ namespace mongo { + stringstream ss; + base64::encode( ss, (const char *)data, len ); + string ret = ss.str(); +- return *rval = c.toval( ret.c_str() ); ++ JS_SET_RVAL( cx , vp , c.toval( ret.c_str() ) ); ++ return JS_TRUE; + } + +- JSBool bindataAsHex(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bindataAsHex(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + int len = (int)c.getNumber( obj, "len" ); + void *holder = JS_GetPrivate( cx, obj ); +@@ -750,19 +917,24 @@ namespace mongo { + ss << v; + } + string ret = ss.str(); +- return *rval = c.toval( ret.c_str() ); ++ JS_SET_RVAL( cx , vp , c.toval( ret.c_str() ) ); ++ return JS_TRUE; + } + +- JSBool bindataLength(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bindataLength(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + int len = (int)c.getNumber( obj, "len" ); +- return *rval = c.toval((double) len); ++ JS_SET_RVAL( cx , vp , c.toval((double) len) ); ++ return JS_TRUE; + } + +- JSBool bindataSubtype(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool bindataSubtype(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + int t = (int)c.getNumber( obj, "type" ); +- return *rval = c.toval((double) t); ++ JS_SET_RVAL( cx , vp , c.toval((double) t) ); ++ return JS_TRUE; + } + + void bindata_finalize( JSContext * cx , JSObject * obj ) { +@@ -774,20 +946,21 @@ namespace mongo { + } + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass bindata_class = { + "BinData" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, bindata_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSFunctionSpec bindata_functions[] = { +- { "toString" , bindata_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "hex", bindataAsHex, 0, JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "base64", bindataBase64, 0, JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "length", bindataLength, 0, JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "subtype", bindataSubtype, 0, JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "toString" , bindata_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "hex", bindataAsHex, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "base64", bindataBase64, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "length", bindataLength, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "subtype", bindataSubtype, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + + // Map +@@ -796,7 +969,16 @@ namespace mongo { + return s == "put" || s == "get" || s == "_get" || s == "values" || s == "_data" || s == "constructor" ; + } + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool map_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool map_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + if ( argc > 0 ) { + JS_ReportError( cx , "Map takes no arguments" ); + return JS_FALSE; +@@ -808,10 +990,16 @@ namespace mongo { + jsval a = OBJECT_TO_JSVAL( array ); + JS_SetProperty( cx , obj , "_data" , &a ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + +- JSBool map_prop( JSContext *cx, JSObject *obj, jsval idval, jsval *vp ) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSPropertyOp) ++ JSBool map_prop( JSContext *cx, JSObject *obj, jsid id, jsval *vp ){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + Convertor c(cx); + if ( specialMapString( c.toString( idval ) ) ) + return JS_TRUE; +@@ -821,34 +1009,49 @@ namespace mongo { + return JS_FALSE; + } + ++ JSBool strict_map_prop( JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp ){ ++ return map_prop( cx , obj , id , vp ); ++ } ++ ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass map_class = { + "Map" , JSCLASS_HAS_PRIVATE , +- map_prop, JS_PropertyStub, map_prop, map_prop, ++ map_prop, JS_PropertyStub, map_prop, strict_map_prop, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSFunctionSpec map_functions[] = { +- { 0 } ++ JS_FS_END + }; + + + // ----- + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass timestamp_class = { + "Timestamp" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool timestamp_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool timestamp_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + smuassert( cx , "Timestamp needs 0 or 2 args" , argc == 0 || argc == 2 ); + + if ( ! JS_InstanceOf( cx , obj , ×tamp_class , 0 ) ) { + obj = JS_NewObject( cx , ×tamp_class , 0 , 0 ); + CHECKNEWOBJECT( obj, cx, "timestamp_constructor" ); +- *rval = OBJECT_TO_JSVAL( obj ); + } + + Convertor c( cx ); +@@ -864,21 +1067,30 @@ namespace mongo { + return JS_TRUE; + } + +- ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass numberlong_class = { + "NumberLong" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool numberlong_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool numberlong_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + smuassert( cx , "NumberLong needs 0 or 1 args" , argc == 0 || argc == 1 ); + + if ( ! JS_InstanceOf( cx , obj , &numberlong_class , 0 ) ) { + obj = JS_NewObject( cx , &numberlong_class , 0 , 0 ); + CHECKNEWOBJECT( obj, cx, "numberlong_constructor" ); +- *rval = OBJECT_TO_JSVAL( obj ); + } + + Convertor c( cx ); +@@ -903,19 +1115,25 @@ namespace mongo { + c.makeLongObj( n, obj ); + } + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + +- JSBool numberlong_valueof(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool numberlong_valueof(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); +- return *rval = c.toval( double( c.toNumberLongUnsafe( obj ) ) ); ++ JS_SET_RVAL( cx , vp , c.toval( double( c.toNumberLongUnsafe( obj ) ) ) ); ++ return JS_TRUE; + } + +- JSBool numberlong_tonumber(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { +- return numberlong_valueof( cx, obj, argc, argv, rval ); ++ JSBool numberlong_tonumber(JSContext *cx, uintN argc, jsval *vp){ ++ return numberlong_valueof( cx, argc, vp ); + } + +- JSBool numberlong_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { ++ JSBool numberlong_tostring(JSContext *cx, uintN argc, jsval *vp){ ++ JSObject *obj = JS_THIS_OBJECT( cx , vp ); + Convertor c(cx); + stringstream ss; + long long val = c.toNumberLongUnsafe( obj ); +@@ -927,33 +1145,45 @@ namespace mongo { + ss << "NumberLong(" << val << ")"; + + string ret = ss.str(); +- return *rval = c.toval( ret.c_str() ); ++ JS_SET_RVAL( cx , vp , c.toval( ret.c_str() ) ); ++ return JS_TRUE; + } + + JSFunctionSpec numberlong_functions[] = { +- { "valueOf" , numberlong_valueof , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "toNumber" , numberlong_tonumber , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { "toString" , numberlong_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT, 0 } , +- { 0 } ++ JS_FS( "valueOf" , numberlong_valueof , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "toNumber" , numberlong_tonumber , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS( "toString" , numberlong_tostring , 0 , JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE ) , ++ JS_FS_END + }; + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp) + JSClass minkey_class = { + "MinKey" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + JSClass maxkey_class = { + "MaxKey" , JSCLASS_HAS_PRIVATE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + + // dbquery + ++#ifdef JSFUN_CONSTRUCTOR ++ JSBool dbquery_constructor( JSContext* cx, uintN argc, jsval* vp ){ ++ jsval *argv = JS_ARGV( cx , vp ); ++ JSObject *obj = JS_NewObjectForConstructor( cx , vp ); ++ if( ! obj ) { ++ JS_ReportError( cx , "Failed to create 'this' object" ); ++ return JS_FALSE; ++ } ++#else + JSBool dbquery_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { ++#endif + smuassert( cx , "DDQuery needs at least 4 args" , argc >= 4 ); + + Convertor c(cx); +@@ -1001,28 +1231,35 @@ namespace mongo { + c.setProperty( obj , "_numReturned" , JSVAL_ZERO ); + c.setProperty( obj , "_special" , JSVAL_FALSE ); + ++#ifdef JSFUN_CONSTRUCTOR ++ JS_SET_RVAL( cx , vp , OBJECT_TO_JSVAL( obj ) ); ++#endif + return JS_TRUE; + } + +- JSBool dbquery_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ) { ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSResolveOp) ++ JSBool dbquery_resolve( JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp ){ ++ jsval idval; ++ JS_IdToValue( cx , id , &idval ); + if ( flags & JSRESOLVE_ASSIGNING ) + return JS_TRUE; + +- if ( ! JSVAL_IS_NUMBER( id ) ) ++ if ( ! JSVAL_IS_NUMBER( idval ) ) + return JS_TRUE; + + jsval val = JSVAL_VOID; +- assert( JS_CallFunctionName( cx , obj , "arrayAccess" , 1 , &id , &val ) ); ++ assert( JS_CallFunctionName( cx , obj , "arrayAccess" , 1 , &idval , &val ) ); + Convertor c(cx); +- c.setProperty( obj , c.toString( id ).c_str() , val ); ++ c.setProperty( obj , c.toString( idval ).c_str() , val ); + *objp = obj; + return JS_TRUE; + } + ++ // FIXME: This won't build on spidermonkey < 1.8.5 (JSStrictPropertyOp, JSResolveOp) + JSClass dbquery_class = { + "DBQuery" , JSCLASS_NEW_RESOLVE , +- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, +- JS_EnumerateStub, (JSResolveOp)(&dbquery_resolve) , JS_ConvertStub, JS_FinalizeStub, ++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, ++ JS_EnumerateStub, (JSResolveOp)dbquery_resolve , JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS + }; + +@@ -1102,7 +1339,7 @@ namespace mongo { + return true; + } + +-#if defined( SM16 ) || defined( MOZJS ) ++#if defined( SM16 ) || JS_VERSION >= 181 + #warning dates do not work in your version of spider monkey + { + jsdouble d = js_DateGetMsecSinceEpoch( c->_context , o ); +@@ -1150,7 +1387,7 @@ namespace mongo { + } + + bool isDate( JSContext * cx , JSObject * o ) { +-#if defined( SM16 ) || defined( MOZJS ) || defined( XULRUNNER ) ++#if defined( SM16 ) || JS_VERSION >= 181 || defined( XULRUNNER ) + return js_DateGetMsecSinceEpoch( cx , o ) != 0; + #else + return JS_InstanceOf( cx , o, &js_DateClass, 0 ); |