diff --git a/scripting/engine_v8.cpp b/scripting/engine_v8.cpp index 38b78aa748d..0030ac0fc10 100644 --- a/scripting/engine_v8.cpp +++ b/scripting/engine_v8.cpp @@ -52,15 +52,15 @@ namespace mongo { _this = Persistent< v8::Object >::New( v8::Object::New() ); - _global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)->GetFunction() ); - _global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)->GetFunction() ); + _global->Set(v8::String::New("print"), newV8Function< Print >()->GetFunction() ); + _global->Set(v8::String::New("version"), newV8Function< Version >()->GetFunction() ); _global->Set(v8::String::New("load"), - v8::FunctionTemplate::New(loadCallback, v8::External::New(this))->GetFunction() ); + v8::FunctionTemplate::New( v8Callback< loadCallback >, v8::External::New(this))->GetFunction() ); _wrapper = Persistent< v8::Function >::New( getObjectWrapperTemplate()->GetFunction() ); - _global->Set(v8::String::New("gc"), v8::FunctionTemplate::New(GCV8)->GetFunction() ); + _global->Set(v8::String::New("gc"), newV8Function< GCV8 >()->GetFunction() ); installDBTypes( _global ); @@ -388,7 +388,7 @@ namespace mongo { void V8Scope::injectNative( const char *field, NativeFunction func ){ V8_SIMPLE_HEADER - Handle< FunctionTemplate > f( v8::FunctionTemplate::New( nativeCallback ) ); + Handle< FunctionTemplate > f( newV8Function< nativeCallback >() ); f->Set( v8::String::New( "_native_function" ), External::New( (void*)func ) ); _global->Set( v8::String::New( field ), f->GetFunction() ); } diff --git a/scripting/v8_db.cpp b/scripting/v8_db.cpp index f4acac001d9..347ca0debf8 100644 --- a/scripting/v8_db.cpp +++ b/scripting/v8_db.cpp @@ -32,21 +32,26 @@ namespace mongo { #define DDD(x) v8::Handle getMongoFunctionTemplate( bool local ){ - v8::Local mongo = FunctionTemplate::New( local ? mongoConsLocal : mongoConsExternal ); + v8::Local mongo; + if ( local ) { + mongo = newV8Function< mongoConsLocal >(); + } else { + mongo = newV8Function< mongoConsExternal >(); + } mongo->InstanceTemplate()->SetInternalFieldCount( 1 ); v8::Local proto = mongo->PrototypeTemplate(); - proto->Set( v8::String::New( "find" ) , FunctionTemplate::New( mongoFind ) ); - proto->Set( v8::String::New( "insert" ) , FunctionTemplate::New( mongoInsert ) ); - proto->Set( v8::String::New( "remove" ) , FunctionTemplate::New( mongoRemove ) ); - proto->Set( v8::String::New( "update" ) , FunctionTemplate::New( mongoUpdate ) ); + proto->Set( v8::String::New( "find" ) , newV8Function< mongoFind >() ); + proto->Set( v8::String::New( "insert" ) , newV8Function< mongoInsert >() ); + proto->Set( v8::String::New( "remove" ) , newV8Function< mongoRemove >() ); + proto->Set( v8::String::New( "update" ) , newV8Function< mongoUpdate >() ); - Local ic = FunctionTemplate::New( internalCursorCons ); + Local ic = newV8Function< internalCursorCons >(); ic->InstanceTemplate()->SetInternalFieldCount( 1 ); - ic->PrototypeTemplate()->Set( v8::String::New("next") , FunctionTemplate::New( internalCursorNext ) ); - ic->PrototypeTemplate()->Set( v8::String::New("hasNext") , FunctionTemplate::New( internalCursorHasNext ) ); - ic->PrototypeTemplate()->Set( v8::String::New("objsLeftInBatch") , FunctionTemplate::New( internalCursorObjsLeftInBatch ) ); + ic->PrototypeTemplate()->Set( v8::String::New("next") , newV8Function< internalCursorNext >() ); + ic->PrototypeTemplate()->Set( v8::String::New("hasNext") , newV8Function< internalCursorHasNext >() ); + ic->PrototypeTemplate()->Set( v8::String::New("objsLeftInBatch") , newV8Function< internalCursorObjsLeftInBatch >() ); proto->Set( v8::String::New( "internalCursor" ) , ic ); @@ -55,44 +60,44 @@ namespace mongo { } v8::Handle getNumberLongFunctionTemplate() { - v8::Local numberLong = FunctionTemplate::New( numberLongInit ); + v8::Local numberLong = newV8Function< numberLongInit >(); v8::Local proto = numberLong->PrototypeTemplate(); - proto->Set( v8::String::New( "valueOf" ) , FunctionTemplate::New( numberLongValueOf ) ); - proto->Set( v8::String::New( "toNumber" ) , FunctionTemplate::New( numberLongToNumber ) ); - proto->Set( v8::String::New( "toString" ) , FunctionTemplate::New( numberLongToString ) ); + proto->Set( v8::String::New( "valueOf" ) , newV8Function< numberLongValueOf >() ); + proto->Set( v8::String::New( "toNumber" ) , newV8Function< numberLongToNumber >() ); + proto->Set( v8::String::New( "toString" ) , newV8Function< numberLongToString >() ); return numberLong; } v8::Handle getBinDataFunctionTemplate() { - v8::Local binData = FunctionTemplate::New( binDataInit ); + v8::Local binData = newV8Function< binDataInit >(); v8::Local proto = binData->PrototypeTemplate(); - proto->Set( v8::String::New( "toString" ) , FunctionTemplate::New( binDataToString ) ); + proto->Set( v8::String::New( "toString" ) , newV8Function< binDataToString >() ); return binData; } void installDBTypes( Handle& global ){ - v8::Local db = FunctionTemplate::New( dbInit ); + v8::Local db = newV8Function< dbInit >(); db->InstanceTemplate()->SetNamedPropertyHandler( collectionFallback ); global->Set(v8::String::New("DB") , db ); - v8::Local dbCollection = FunctionTemplate::New( collectionInit ); + v8::Local dbCollection = newV8Function< collectionInit >(); dbCollection->InstanceTemplate()->SetNamedPropertyHandler( collectionFallback ); global->Set(v8::String::New("DBCollection") , dbCollection ); - v8::Local dbQuery = FunctionTemplate::New( dbQueryInit ); + v8::Local dbQuery = newV8Function< dbQueryInit >(); dbQuery->InstanceTemplate()->SetIndexedPropertyHandler( dbQueryIndexAccess ); global->Set(v8::String::New("DBQuery") , dbQuery ); - global->Set( v8::String::New("ObjectId") , FunctionTemplate::New( objectIdInit ) ); + global->Set( v8::String::New("ObjectId") , newV8Function< objectIdInit >() ); - global->Set( v8::String::New("DBRef") , FunctionTemplate::New( dbRefInit ) ); + global->Set( v8::String::New("DBRef") , newV8Function< dbRefInit >() ); - global->Set( v8::String::New("DBPointer") , FunctionTemplate::New( dbPointerInit ) ); + global->Set( v8::String::New("DBPointer") , newV8Function< dbPointerInit >() ); global->Set( v8::String::New("BinData") , getBinDataFunctionTemplate() ); @@ -101,24 +106,24 @@ namespace mongo { } void installDBTypes( Handle& global ){ - v8::Local db = FunctionTemplate::New( dbInit ); + v8::Local db = newV8Function< dbInit >(); db->InstanceTemplate()->SetNamedPropertyHandler( collectionFallback ); global->Set(v8::String::New("DB") , db->GetFunction() ); - v8::Local dbCollection = FunctionTemplate::New( collectionInit ); + v8::Local dbCollection = newV8Function< collectionInit >(); dbCollection->InstanceTemplate()->SetNamedPropertyHandler( collectionFallback ); global->Set(v8::String::New("DBCollection") , dbCollection->GetFunction() ); - v8::Local dbQuery = FunctionTemplate::New( dbQueryInit ); + v8::Local dbQuery = newV8Function< dbQueryInit >(); dbQuery->InstanceTemplate()->SetIndexedPropertyHandler( dbQueryIndexAccess ); global->Set(v8::String::New("DBQuery") , dbQuery->GetFunction() ); - global->Set( v8::String::New("ObjectId") , FunctionTemplate::New( objectIdInit )->GetFunction() ); + global->Set( v8::String::New("ObjectId") , newV8Function< objectIdInit >()->GetFunction() ); - global->Set( v8::String::New("DBRef") , FunctionTemplate::New( dbRefInit )->GetFunction() ); + global->Set( v8::String::New("DBRef") , newV8Function< dbRefInit >()->GetFunction() ); - global->Set( v8::String::New("DBPointer") , FunctionTemplate::New( dbPointerInit )->GetFunction() ); + global->Set( v8::String::New("DBPointer") , newV8Function< dbPointerInit >()->GetFunction() ); global->Set( v8::String::New("BinData") , getBinDataFunctionTemplate()->GetFunction() ); @@ -132,7 +137,7 @@ namespace mongo { global->Set( v8::String::New("MaxKey"), mongoToV8Element( i.next() ) ); global->Set( v8::String::New("MinKey"), mongoToV8Element( i.next() ) ); - global->Get( v8::String::New( "Object" ) )->ToObject()->Set( v8::String::New("bsonsize") , FunctionTemplate::New( bsonsize )->GetFunction() ); + global->Get( v8::String::New( "Object" ) )->ToObject()->Set( v8::String::New("bsonsize") , newV8Function< bsonsize >()->GetFunction() ); } void destroyConnection( Persistent self, void* parameter){ @@ -367,19 +372,15 @@ namespace mongo { } v8::Handle internalCursorNext(const v8::Arguments& args){ - try { - mongo::DBClientCursor * cursor = getCursor( args ); - if ( ! cursor ) - return v8::Undefined(); - BSONObj o; - { - v8::Unlocker u; - o = cursor->next(); - } - return mongoToV8( o ); - } catch ( ... ) { - return v8::ThrowException( v8::String::New( "unexpected exception in internalCursorNext()" ) ); + mongo::DBClientCursor * cursor = getCursor( args ); + if ( ! cursor ) + return v8::Undefined(); + BSONObj o; + { + v8::Unlocker u; + o = cursor->next(); } + return mongoToV8( o ); } v8::Handle internalCursorHasNext(const v8::Arguments& args){ diff --git a/scripting/v8_db.h b/scripting/v8_db.h index 4bebb32ba35..eacf5a839c8 100644 --- a/scripting/v8_db.h +++ b/scripting/v8_db.h @@ -76,3 +76,19 @@ namespace mongo { v8::Handle bsonsize( const v8::Arguments& args ); } + +template < v8::Handle< v8::Value > ( *f ) ( const v8::Arguments& ) > +v8::Handle< v8::Value > v8Callback( const v8::Arguments &args ) { + try { + return f( args ); + } catch( const std::exception &e ) { + return v8::ThrowException( v8::String::New( e.what() ) ); + } catch( ... ) { + return v8::ThrowException( v8::String::New( "unknown exception" ) ); + } +} + +template < v8::Handle< v8::Value > ( *f ) ( const v8::Arguments& ) > +v8::Local< v8::FunctionTemplate > newV8Function() { + return v8::FunctionTemplate::New( v8Callback< f > ); +} \ No newline at end of file diff --git a/scripting/v8_utils.cpp b/scripting/v8_utils.cpp index 5a07a802dc1..85ac70c22fd 100644 --- a/scripting/v8_utils.cpp +++ b/scripting/v8_utils.cpp @@ -16,6 +16,7 @@ */ #include "v8_utils.h" +#include "v8_db.h" #include #include #include @@ -275,10 +276,10 @@ namespace mongo { Local o = args[0]->ToObject(); - o->Set( v8::String::New( "init" ) , FunctionTemplate::New( ThreadInit )->GetFunction() ); - o->Set( v8::String::New( "start" ) , FunctionTemplate::New( ThreadStart )->GetFunction() ); - o->Set( v8::String::New( "join" ) , FunctionTemplate::New( ThreadJoin )->GetFunction() ); - o->Set( v8::String::New( "returnData" ) , FunctionTemplate::New( ThreadReturnData )->GetFunction() ); + o->Set( v8::String::New( "init" ) , newV8Function< ThreadInit >()->GetFunction() ); + o->Set( v8::String::New( "start" ) , newV8Function< ThreadStart >()->GetFunction() ); + o->Set( v8::String::New( "join" ) , newV8Function< ThreadJoin >()->GetFunction() ); + o->Set( v8::String::New( "returnData" ) , newV8Function< ThreadReturnData >()->GetFunction() ); return v8::Undefined(); } @@ -289,7 +290,7 @@ namespace mongo { Local o = args[0]->ToObject(); - o->Set( v8::String::New( "init" ) , FunctionTemplate::New( ScopedThreadInit )->GetFunction() ); + o->Set( v8::String::New( "init" ) , newV8Function< ScopedThreadInit >()->GetFunction() ); // inheritance takes care of other member functions return v8::Undefined(); @@ -298,8 +299,8 @@ namespace mongo { void installFork( v8::Handle< v8::Object > &global, v8::Handle< v8::Context > &context ) { if ( baseContext_.IsEmpty() ) // if this is the shell, first call will be with shell context, otherwise don't expect to use fork() anyway baseContext_ = context; - global->Set( v8::String::New( "_threadInject" ), FunctionTemplate::New( ThreadInject )->GetFunction() ); - global->Set( v8::String::New( "_scopedThreadInject" ), FunctionTemplate::New( ScopedThreadInject )->GetFunction() ); + global->Set( v8::String::New( "_threadInject" ), newV8Function< ThreadInject >()->GetFunction() ); + global->Set( v8::String::New( "_scopedThreadInject" ), newV8Function< ScopedThreadInject >()->GetFunction() ); } Handle GCV8(const Arguments& args) { diff --git a/scripting/v8_wrapper.cpp b/scripting/v8_wrapper.cpp index b82e01c531a..149da4f6c97 100644 --- a/scripting/v8_wrapper.cpp +++ b/scripting/v8_wrapper.cpp @@ -17,6 +17,7 @@ #include "v8_wrapper.h" #include "v8_utils.h" +#include "v8_db.h" #include @@ -602,7 +603,7 @@ namespace mongo { } v8::Handle getObjectWrapperTemplate(){ - v8::Local t = FunctionTemplate::New( wrapperCons ); + v8::Local t = newV8Function< wrapperCons >(); t->InstanceTemplate()->SetNamedPropertyHandler( wrapperGetHandler ); return t; }