void operator()() { _config._scope.reset(static_cast<V8Scope*>(globalScriptEngine->newScope())); v8::Locker v8lock(_config._scope->getIsolate()); v8::Isolate::Scope iscope(_config._scope->getIsolate()); v8::HandleScope handle_scope; v8::Context::Scope context_scope(_config._scope->getContext()); BSONObj args = _config._args; v8::Local<v8::Function> f = v8::Function::Cast( *(_config._scope->mongoToV8Element(args.firstElement(), true))); int argc = args.nFields() - 1; // TODO SERVER-8016: properly allocate handles on the stack v8::Local<v8::Value> argv[24]; BSONObjIterator it(args); it.next(); for(int i = 0; i < argc && i < 24; ++i) { argv[i] = v8::Local<v8::Value>::New( _config._scope->mongoToV8Element(*it, true)); it.next(); } v8::TryCatch try_catch; v8::Handle<v8::Value> ret = f->Call(_config._scope->getContext()->Global(), argc, argv); if (ret.IsEmpty() || try_catch.HasCaught()) { string e = _config._scope->v8ExceptionToSTLString(&try_catch); log() << "js thread raised exception: " << e << endl; ret = v8::Undefined(); } // ret is translated to BSON to switch isolate BSONObjBuilder b; _config._scope->v8ToMongoElement(b, "ret", ret); _config._returnData = b.obj(); }
void operator()() { config_._scope.reset( dynamic_cast< V8Scope * >( globalScriptEngine->newScope() ) ); v8::Locker v8lock(config_._scope->getIsolate()); v8::Isolate::Scope iscope(config_._scope->getIsolate()); HandleScope handle_scope; Context::Scope context_scope(config_._scope->getContext()); BSONObj args = config_.args_; Local< v8::Function > f = v8::Function::Cast( *(config_._scope->mongoToV8Element(args.firstElement(), true)) ); int argc = args.nFields() - 1; // TODO SERVER-8016: properly allocate handles on the stack Local<Value> argv[24]; BSONObjIterator it(args); it.next(); for(int i = 0; i < argc && i < 24; ++i) { argv[i] = Local< Value >::New(config_._scope->mongoToV8Element(*it, true)); it.next(); } TryCatch try_catch; Handle<Value> ret = f->Call(config_._scope->getContext()->Global(), argc, argv); if (ret.IsEmpty() || try_catch.HasCaught()) { string e = toSTLString( &try_catch ); log() << "js thread raised exception: " << e << endl; // v8 probably does something sane if ret is empty, but not going to assume that for now ret = v8::Undefined(); } // ret is translated to BSON to switch isolate BSONObjBuilder b; config_._scope->v8ToMongoElement(b, "ret", ret); config_.returnData_ = b.obj(); }
void operator()() { V8Scope* scope = config_._scope.get(); v8::Isolate::Scope iscope(scope->getIsolate()); v8::Locker l(scope->getIsolate()); HandleScope handle_scope; Context::Scope context_scope( scope->getContext() ); BSONObj args = config_.args_; Local< v8::Function > f = v8::Function::Cast( *(scope->mongoToV8Element(args.firstElement(), true)) ); int argc = args.nFields() - 1; boost::scoped_array< Local< Value > > argv( new Local< Value >[ argc ] ); BSONObjIterator it(args); it.next(); for( int i = 0; i < argc; ++i ) { argv[ i ] = Local< Value >::New( scope->mongoToV8Element(*it, true) ); it.next(); } TryCatch try_catch; Handle< Value > ret = f->Call( scope->getContext()->Global(), argc, argv.get() ); if ( ret.IsEmpty() ) { string e = toSTLString( &try_catch ); log() << "js thread raised exception: " << e << endl; // v8 probably does something sane if ret is empty, but not going to assume that for now ret = v8::Undefined(); } // ret is translated to BSON to switch isolate BSONObjBuilder b; scope->v8ToMongoElement(b, "ret", ret); config_.returnData_ = b.obj(); }
void operator()() { try { _config._scope.reset(static_cast<V8Scope*>(globalScriptEngine->newScope())); v8::Locker v8lock(_config._scope->getIsolate()); v8::Isolate::Scope iscope(_config._scope->getIsolate()); v8::HandleScope handle_scope(_config._scope->getIsolate()); v8::Context::Scope context_scope(_config._scope->getContext()); BSONObj args = _config._args; v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( v8::Local<v8::Value>( _config._scope->mongoToV8Element(args.firstElement(), true))); int argc = args.nFields() - 1; // TODO SERVER-8016: properly allocate handles on the stack v8::Local<v8::Value> argv[24]; BSONObjIterator it(args); it.next(); for(int i = 0; i < argc && i < 24; ++i) { argv[i] = v8::Local<v8::Value>::New( _config._scope->getIsolate(), _config._scope->mongoToV8Element(*it, true)); it.next(); } v8::TryCatch try_catch; v8::Local<v8::Value> ret = f->Call(_config._scope->getGlobal(), argc, argv); if (ret.IsEmpty() || try_catch.HasCaught()) { string e = _config._scope->v8ExceptionToSTLString(&try_catch); log() << "js thread raised js exception: " << e << endl; ret = v8::Undefined(_config._scope->getIsolate()); // TODO propagate exceptions (or at least the fact that an exception was // thrown) to the calling js on either join() or returnData(). } // ret is translated to BSON to switch isolate BSONObjBuilder b; _config._scope->v8ToMongoElement(b, "ret", ret); _config._returnData = b.obj(); } catch (const DBException& e) { // Keeping behavior the same as for js exceptions. log() << "js thread threw c++ exception: " << e.toString(); _config._returnData = BSON("ret" << BSONUndefined); } catch (const std::exception& e) { log() << "js thread threw c++ exception: " << e.what(); _config._returnData = BSON("ret" << BSONUndefined); } catch (...) { log() << "js thread threw c++ non-exception"; _config._returnData = BSON("ret" << BSONUndefined); } }