summaryrefslogtreecommitdiff
path: root/src/mongo/scripting/v8_utils.cpp
diff options
context:
space:
mode:
authorBen Becker <ben.becker@10gen.com>2013-01-02 16:42:09 -0800
committerBen Becker <ben.becker@10gen.com>2013-01-02 16:42:09 -0800
commitae5a98ca54b4c9287cf7634d8086a44930f7c0b5 (patch)
treed19cf721147017dd3d69e2af16ea8e823b926dd1 /src/mongo/scripting/v8_utils.cpp
parent0c99deae0ce63b0ae000175cbc4d446aa094d2de (diff)
downloadmongo-ae5a98ca54b4c9287cf7634d8086a44930f7c0b5.tar.gz
Bulk v8 cleanup:
- conventions and consistency - added some comments - removed some dead code - always use v8:: prefix and don't use namespace v8 - removed redundant arg handles in v8/mongo conversion functions - removed redundant erase logic in loadStored() - s/exec error:/JavaScript error:/ - in v8-specific files, changed jsassert to use uassert instead of verify - replaced verify() w/ uassert and massert Includes fix for SERVER-7751.
Diffstat (limited to 'src/mongo/scripting/v8_utils.cpp')
-rw-r--r--src/mongo/scripting/v8_utils.cpp180
1 files changed, 82 insertions, 98 deletions
diff --git a/src/mongo/scripting/v8_utils.cpp b/src/mongo/scripting/v8_utils.cpp
index 8d00b63f9d5..43aaafd7989 100644
--- a/src/mongo/scripting/v8_utils.cpp
+++ b/src/mongo/scripting/v8_utils.cpp
@@ -15,14 +15,6 @@
* limitations under the License.
*/
-#if defined(_WIN32)
-/** this is a hack - v8stdint.h defined uint16_t etc. on _WIN32 only, and that collides with
- our usage of boost */
-#include "boost/cstdint.hpp"
-using namespace boost;
-#define V8STDINT_H_
-#endif
-
#include "mongo/scripting/v8_utils.h"
#include <boost/smart_ptr.hpp>
@@ -33,36 +25,31 @@ using namespace boost;
#include <sstream>
#include <vector>
+#include "mongo/platform/cstdint.h"
#include "mongo/scripting/engine_v8.h"
#include "mongo/scripting/v8_db.h"
#include "mongo/util/mongoutils/str.h"
using namespace std;
-using namespace v8;
namespace mongo {
- std::string toSTLString( const Handle<v8::Value> & o ) {
+ std::string toSTLString(const v8::Handle<v8::Value>& o) {
v8::String::Utf8Value str(o);
const char * foo = *str;
std::string s(foo);
return s;
}
- std::string toSTLString( const v8::TryCatch * try_catch ) {
-
+ std::string toSTLString(const v8::TryCatch* try_catch) {
stringstream ss;
-
- //while ( try_catch ){ // disabled for v8 bleeding edge
-
v8::String::Utf8Value exception(try_catch->Exception());
- Handle<v8::Message> message = try_catch->Message();
+ v8::Handle<v8::Message> message = try_catch->Message();
if (message.IsEmpty()) {
ss << *exception << endl;
}
else {
-
v8::String::Utf8Value filename(message->GetScriptResourceName());
if (*filename) {
int linenum = message->GetLineNumber();
@@ -83,30 +70,24 @@ namespace mongo {
ss << endl;
}
-
- //try_catch = try_catch->next_;
- //}
-
return ss.str();
}
-
- std::ostream& operator<<( std::ostream &s, const Handle<v8::Value> & o ) {
+ std::ostream& operator<<(std::ostream& s, const v8::Handle<v8::Value>& o) {
v8::String::Utf8Value str(o);
s << *str;
return s;
}
- std::ostream& operator<<( std::ostream &s, const v8::TryCatch * try_catch ) {
- HandleScope handle_scope;
+ std::ostream& operator<<(std::ostream& s, const v8::TryCatch* try_catch) {
+ v8::HandleScope handle_scope;
v8::String::Utf8Value exception(try_catch->Exception());
- Handle<v8::Message> message = try_catch->Message();
+ v8::Handle<v8::Message> message = try_catch->Message();
if (message.IsEmpty()) {
s << *exception << endl;
}
else {
-
v8::String::Utf8Value filename(message->GetScriptResourceName());
int linenum = message->GetLineNumber();
cout << *filename << ":" << linenum << " " << *exception << endl;
@@ -124,10 +105,6 @@ namespace mongo {
cout << endl;
}
-
- //if ( try_catch->next_ ) // disabled for v8 bleeding edge
- // s << try_catch->next_;
-
return s;
}
@@ -137,158 +114,165 @@ namespace mongo {
class JSThreadConfig {
public:
- JSThreadConfig( V8Scope* scope, const Arguments &args, bool newScope = false ) : started_(), done_(), newScope_( newScope ) {
- jsassert( args.Length() > 0, "need at least one argument" );
- jsassert( args[ 0 ]->IsFunction(), "first argument must be a function" );
+ JSThreadConfig(V8Scope* scope, const v8::Arguments& args, bool newScope = false) :
+ _started(),
+ _done(),
+ _newScope(newScope) {
+ jsassert(args.Length() > 0, "need at least one argument");
+ jsassert(args[0]->IsFunction(), "first argument must be a function");
// arguments need to be copied into the isolate, go through bson
BSONObjBuilder b;
- for( int i = 0; i < args.Length(); ++i ) {
+ for(int i = 0; i < args.Length(); ++i) {
scope->v8ToMongoElement(b, mongoutils::str::stream() << "arg" << i, args[i]);
}
- args_ = b.obj();
+ _args = b.obj();
}
~JSThreadConfig() {
}
void start() {
- jsassert( !started_, "Thread already started" );
- JSThread jt( *this );
- thread_.reset( new boost::thread( jt ) );
- started_ = true;
+ jsassert(!_started, "Thread already started");
+ JSThread jt(*this);
+ _thread.reset(new boost::thread(jt));
+ _started = true;
}
void join() {
- jsassert( started_ && !done_, "Thread not running" );
- thread_->join();
- done_ = true;
+ jsassert(_started && !_done, "Thread not running");
+ _thread->join();
+ _done = true;
}
BSONObj returnData() {
- if ( !done_ )
+ if (!_done)
join();
- return returnData_;
+ return _returnData;
}
private:
class JSThread {
public:
- JSThread( JSThreadConfig &config ) : config_( config ) {}
+ JSThread(JSThreadConfig& config) : _config(config) {}
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)) );
+ _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
- Local<Value> argv[24];
+ v8::Local<v8::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));
+ argv[i] = v8::Local<v8::Value>::New(
+ _config._scope->mongoToV8Element(*it, true));
it.next();
}
- TryCatch try_catch;
- Handle<Value> ret = f->Call(config_._scope->getContext()->Global(), argc, argv);
+ 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 = toSTLString( &try_catch );
+ 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();
+ _config._scope->v8ToMongoElement(b, "ret", ret);
+ _config._returnData = b.obj();
}
private:
- JSThreadConfig &config_;
+ JSThreadConfig& _config;
};
- bool started_;
- bool done_;
- bool newScope_;
- BSONObj args_;
- scoped_ptr< boost::thread > thread_;
- scoped_ptr< V8Scope > _scope;
- BSONObj returnData_;
+ bool _started;
+ bool _done;
+ bool _newScope;
+ BSONObj _args;
+ scoped_ptr<boost::thread> _thread;
+ scoped_ptr<V8Scope> _scope;
+ BSONObj _returnData;
};
- Handle< Value > ThreadInit( V8Scope* scope, const Arguments &args ) {
- Handle<v8::Object> it = args.This();
+ v8::Handle<v8::Value> ThreadInit(V8Scope* scope, const v8::Arguments& args) {
+ v8::Handle<v8::Object> it = args.This();
// NOTE I believe the passed JSThreadConfig will never be freed. If this
// policy is changed, JSThread may no longer be able to store JSThreadConfig
// by reference.
- it->SetHiddenValue( v8::String::New( "_JSThreadConfig" ), External::New( new JSThreadConfig( scope, args ) ) );
+ it->SetHiddenValue(v8::String::New("_JSThreadConfig"),
+ v8::External::New(new JSThreadConfig(scope, args)));
return v8::Undefined();
}
- Handle< Value > ScopedThreadInit( V8Scope* scope, const Arguments &args ) {
- Handle<v8::Object> it = args.This();
+ v8::Handle<v8::Value> ScopedThreadInit(V8Scope* scope, const v8::Arguments& args) {
+ v8::Handle<v8::Object> it = args.This();
// NOTE I believe the passed JSThreadConfig will never be freed. If this
// policy is changed, JSThread may no longer be able to store JSThreadConfig
// by reference.
- it->SetHiddenValue( v8::String::New( "_JSThreadConfig" ), External::New( new JSThreadConfig( scope, args, true ) ) );
+ it->SetHiddenValue(v8::String::New("_JSThreadConfig"),
+ v8::External::New(new JSThreadConfig(scope, args, true)));
return v8::Undefined();
}
- JSThreadConfig *thisConfig( V8Scope* scope, const Arguments &args ) {
- Local< External > c = External::Cast( *(args.This()->GetHiddenValue( v8::String::New( "_JSThreadConfig" ) ) ) );
- JSThreadConfig *config = (JSThreadConfig *)( c->Value() );
+ JSThreadConfig *thisConfig(V8Scope* scope, const v8::Arguments& args) {
+ v8::Local<v8::External> c = v8::External::Cast(
+ *(args.This()->GetHiddenValue(v8::String::New("_JSThreadConfig"))));
+ JSThreadConfig *config = (JSThreadConfig *)(c->Value());
return config;
}
- Handle< Value > ThreadStart( V8Scope* scope, const Arguments &args ) {
- thisConfig( scope, args )->start();
+ v8::Handle<v8::Value> ThreadStart(V8Scope* scope, const v8::Arguments& args) {
+ thisConfig(scope, args)->start();
return v8::Undefined();
}
- Handle< Value > ThreadJoin( V8Scope* scope, const Arguments &args ) {
- thisConfig( scope, args )->join();
+ v8::Handle<v8::Value> ThreadJoin(V8Scope* scope, const v8::Arguments& args) {
+ thisConfig(scope, args)->join();
return v8::Undefined();
}
- Handle< Value > ThreadReturnData( V8Scope* scope, const Arguments &args ) {
- BSONObj data = thisConfig( scope, args )->returnData();
+ v8::Handle<v8::Value> ThreadReturnData(V8Scope* scope, const v8::Arguments& args) {
+ BSONObj data = thisConfig(scope, args)->returnData();
return scope->mongoToV8Element(data.firstElement(), true);
}
- Handle< Value > ThreadInject( V8Scope* scope, const Arguments &args ) {
+ v8::Handle<v8::Value> ThreadInject(V8Scope* scope, const v8::Arguments& args) {
v8::HandleScope handle_scope;
- jsassert( args.Length() == 1 , "threadInject takes exactly 1 argument" );
- jsassert( args[0]->IsObject() , "threadInject needs to be passed a prototype" );
-
- Local<v8::Object> o = args[0]->ToObject();
+ jsassert(args.Length() == 1, "threadInject takes exactly 1 argument");
+ jsassert(args[0]->IsObject(), "threadInject needs to be passed a prototype");
+ v8::Local<v8::Object> o = args[0]->ToObject();
// install method on the Thread object
scope->injectV8Function("init", ThreadInit, o);
scope->injectV8Function("start", ThreadStart, o);
scope->injectV8Function("join", ThreadJoin, o);
scope->injectV8Function("returnData", ThreadReturnData, o);
- return handle_scope.Close(v8::Handle<Value>());
+ return handle_scope.Close(v8::Handle<v8::Value>());
}
- Handle< Value > ScopedThreadInject( V8Scope* scope, const Arguments &args ) {
+ v8::Handle<v8::Value> ScopedThreadInject(V8Scope* scope, const v8::Arguments& args) {
v8::HandleScope handle_scope;
- jsassert( args.Length() == 1 , "threadInject takes exactly 1 argument" );
- jsassert( args[0]->IsObject() , "threadInject needs to be passed a prototype" );
-
- Local<v8::Object> o = args[0]->ToObject();
+ jsassert(args.Length() == 1, "threadInject takes exactly 1 argument");
+ jsassert(args[0]->IsObject(), "threadInject needs to be passed a prototype");
+ v8::Local<v8::Object> o = args[0]->ToObject();
scope->injectV8Function("init", ScopedThreadInit, o);
// inheritance takes care of other member functions
- return handle_scope.Close(v8::Handle<Value>());
+ return handle_scope.Close(v8::Handle<v8::Value>());
}
- void installFork( V8Scope* scope, v8::Handle< v8::Object > &global, v8::Handle< v8::Context > &context ) {
+ void installFork(V8Scope* scope, v8::Handle<v8::Object>& global,
+ v8::Handle<v8::Context>& context) {
scope->injectV8Function("_threadInject", ThreadInject, global);
scope->injectV8Function("_scopedThreadInject", ScopedThreadInject, global);
}