diff --git a/jstests/error2.js b/jstests/error2.js index 5f2f5387424..8c27d6250e1 100644 --- a/jstests/error2.js +++ b/jstests/error2.js @@ -6,15 +6,16 @@ f.drop(); f.save( {a:1} ); -c = f.find({$where : function(){ return a() }}); -try { - c.next(); -} catch( e ) { - assert( e.match( /java.lang.NullPointerException/ ) ); -} +assert.throws( + function(){ + c = f.find({$where : function(){ return a() }}); + c.next(); + } +); + +assert.throws( + function(){ + db.eval( function() { return a(); } ); + } +); -try { - db.eval( function() { return a(); } ); -} catch ( e ) { - assert( e.match( /java.lang.NullPointerException/ ) ); -} diff --git a/jstests/eval2.js b/jstests/eval2.js index 08dbcf65ee2..04ecd74d212 100644 --- a/jstests/eval2.js +++ b/jstests/eval2.js @@ -15,4 +15,3 @@ var f = db.group( ); assert(f[0].a == 1 && f[0].csum == 2); - diff --git a/jstests/index8.js b/jstests/index8.js index 5ee05cae4f5..3244253706b 100644 --- a/jstests/index8.js +++ b/jstests/index8.js @@ -7,19 +7,19 @@ t.ensureIndex( { a: 1 } ); t.ensureIndex( { b: 1 }, true ); t.ensureIndex( { c: 1 }, [ false, "cIndex" ] ); -checkIndexes = function() { +checkIndexes = function( num ) { // printjson( db.system.indexes.find( { ns: "test.jstests_index8" } ).toArray() ); indexes = db.system.indexes.find( { ns: "test.jstests_index8" } ).sort( { key: 1 } ); - assert( !indexes[ 0 ].unique ); - assert( indexes[ 1 ].unique ); - assert( !indexes[ 2 ].unique ); - assert.eq( "cIndex", indexes[ 2 ].name ); + assert( !indexes[ 0 ].unique , "A" + num ); + assert( indexes[ 1 ].unique , "B" + num ); + assert( !indexes[ 2 ].unique , "C" + num ); + assert.eq( "cIndex", indexes[ 2 ].name , "D" + num ); } -checkIndexes(); +checkIndexes( 1 ); t.reIndex(); -checkIndexes(); +checkIndexes( 2 ); t.save( { a: 2, b: 1 } ); t.save( { a: 2 } ); diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 7909fc23d4a..988fe38732c 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -72,6 +72,15 @@ namespace mongo { return toObject( JSVAL_TO_OBJECT( v ) ); } + string getFunctionCode( JSFunction * func ){ + return toString( JS_DecompileFunction( _context , func , 0 ) ); + } + + string getFunctionCode( jsval v ){ + uassert( "not a function" , JS_TypeOfValue( _context , v ) == JSTYPE_FUNCTION ); + return getFunctionCode( JS_ValueToFunction( _context , v ) ); + } + void append( BSONObjBuilder& b , string name , jsval val ){ switch ( JS_TypeOfValue( _context , val ) ){ @@ -81,11 +90,42 @@ namespace mongo { case JSTYPE_NUMBER: b.append( name.c_str() , toNumber( val ) ); break; case JSTYPE_STRING: b.append( name.c_str() , toString( val ) ); break; - default: uassert( (string)"can't append type: " + typeString( val ) , 0 ); + case JSTYPE_OBJECT: b.append( name.c_str() , toObject( val ) ); break; + case JSTYPE_FUNCTION: b.appendCode( name.c_str() , getFunctionCode( val ).c_str() ); break; + + default: uassert( (string)"can't append field. name:" + name + " type: " + typeString( val ) , 0 ); } } // ---------- to spider monkey --------- + + bool hasFunctionIdentifier( const string& code ){ + if ( code.size() < 9 || code.find( "function" ) != 0 ) + return false; + + return code[8] == ' ' || code[8] == '('; + } + + JSFunction * compileFunction( const char * code ){ + if ( ! hasFunctionIdentifier( code ) ){ + string s = code; + if ( strstr( code , "return" ) == 0 ) + s = "return " + s; + return JS_CompileFunction( _context , 0 , "anonymous" , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile" , 0 ); + } + + // TODO: there must be a way in spider monkey to do this - this is a total hack + + string s = "return "; + s += code; + s += ";"; + + JSFunction * func = JS_CompileFunction( _context , 0 , "anonymous" , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile" , 0 ); + jsval ret; + JS_CallFunction( _context , 0 , func , 0 , 0 , &ret ); + return JS_ValueToFunction( _context , ret ); + } + jsval toval( double d ){ jsval val; @@ -169,9 +209,13 @@ namespace mongo { assert( r ); return OBJECT_TO_JSVAL( r ); } + case 13:{ + JSFunction * func = compileFunction( e.valuestr() ); + return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); + } case Date: return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , e.date() ) ); - + default: log() << "toval can't handle type: " << (int)(e.type()) << endl; } @@ -516,35 +560,8 @@ namespace mongo { // ---- functions ----- - bool hasFunctionIdentifier( const string& code ){ - if ( code.size() < 9 || code.find( "function" ) != 0 ) - return false; - - return code[8] == ' ' || code[8] == '('; - } - - JSFunction * compileFunction( const char * code ){ - if ( ! hasFunctionIdentifier( code ) ){ - string s = code; - if ( strstr( code , "return" ) == 0 ) - s = "return " + s; - return JS_CompileFunction( _context , 0 , "anonymous" , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile" , 0 ); - } - - // TODO: there must be a way in spider monkey to do this - this is a total hack - - string s = "return "; - s += code; - s += ";"; - - JSFunction * func = JS_CompileFunction( _context , 0 , "anonymous" , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile" , 0 ); - jsval ret; - JS_CallFunction( _context , 0 , func , 0 , 0 , &ret ); - return JS_ValueToFunction( _context , ret ); - } - ScriptingFunction createFunction( const char * code ){ - return (ScriptingFunction)compileFunction( code ); + return (ScriptingFunction)_convertor->compileFunction( code ); } void precall(){