Lint node_script.cc

This commit is contained in:
Ryan Dahl 2010-06-28 17:27:17 -07:00
parent e2db605308
commit 23172c5d85
2 changed files with 83 additions and 101 deletions

View File

@ -2,16 +2,15 @@
#include <node_script.h> #include <node_script.h>
#include <assert.h> #include <assert.h>
#include <v8-debug.h>
using namespace v8; using namespace v8;
using namespace node; using namespace node;
Persistent<FunctionTemplate> node::Context::constructor_template; Persistent<FunctionTemplate> node::Context::constructor_template;
void
node::Context::Initialize (Handle<Object> target) void node::Context::Initialize (Handle<Object> target) {
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(node::Context::New); Local<FunctionTemplate> t = FunctionTemplate::New(node::Context::New);
@ -22,9 +21,8 @@ node::Context::Initialize (Handle<Object> target)
target->Set(String::NewSymbol("Context"), constructor_template->GetFunction()); target->Set(String::NewSymbol("Context"), constructor_template->GetFunction());
} }
Handle<Value>
node::Context::New (const Arguments& args) Handle<Value> node::Context::New (const Arguments& args) {
{
HandleScope scope; HandleScope scope;
node::Context *t = new node::Context(); node::Context *t = new node::Context();
@ -33,31 +31,32 @@ node::Context::New (const Arguments& args)
return args.This(); return args.This();
} }
node::Context::~Context() {
_context.Dispose(); node::Context::Context() : ObjectWrap() {
context_ = v8::Context::New();
} }
Local<Object>
node::Context::NewInstance() node::Context::~Context() {
{ context_.Dispose();
}
Local<Object> node::Context::NewInstance() {
Local<Object> context = constructor_template->GetFunction()->NewInstance(); Local<Object> context = constructor_template->GetFunction()->NewInstance();
node::Context *nContext = ObjectWrap::Unwrap<node::Context>(context);
nContext->_context = v8::Context::New();
return context; return context;
} }
v8::Persistent<v8::Context>
node::Context::GetV8Context() v8::Persistent<v8::Context> node::Context::GetV8Context() {
{ return context_;
return _context;
} }
Persistent<FunctionTemplate> node::Script::constructor_template; Persistent<FunctionTemplate> node::Script::constructor_template;
void
node::Script::Initialize (Handle<Object> target) void node::Script::Initialize (Handle<Object> target) {
{
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(node::Script::New); Local<FunctionTemplate> t = FunctionTemplate::New(node::Script::New);
@ -77,9 +76,8 @@ node::Script::Initialize (Handle<Object> target)
target->Set(String::NewSymbol("Script"), constructor_template->GetFunction()); target->Set(String::NewSymbol("Script"), constructor_template->GetFunction());
} }
Handle<Value>
node::Script::New (const Arguments& args) Handle<Value> node::Script::New (const Arguments& args) {
{
HandleScope scope; HandleScope scope;
node::Script *t = new node::Script(); node::Script *t = new node::Script();
@ -89,14 +87,13 @@ node::Script::New (const Arguments& args)
node::Script::EvalMachine<compileCode, thisContext, wrapExternal>(args); node::Script::EvalMachine<compileCode, thisContext, wrapExternal>(args);
} }
node::Script::~Script() { node::Script::~Script() {
_script.Dispose(); script_.Dispose();
} }
Handle<Value> Handle<Value> node::Script::CreateContext (const Arguments& args) {
node::Script::CreateContext (const Arguments& args)
{
HandleScope scope; HandleScope scope;
Local<v8::Object> context = node::Context::NewInstance(); Local<v8::Object> context = node::Context::NewInstance();
@ -117,92 +114,79 @@ node::Script::CreateContext (const Arguments& args)
return scope.Close(context); return scope.Close(context);
} }
Handle<Value>
node::Script::RunInContext (const Arguments& args) Handle<Value> node::Script::RunInContext (const Arguments& args) {
{
return return
node::Script::EvalMachine<unwrapExternal, userContext, returnResult>(args); node::Script::EvalMachine<unwrapExternal, userContext, returnResult>(args);
} }
Handle<Value> Handle<Value> node::Script::RunInThisContext (const Arguments& args) {
node::Script::RunInThisContext (const Arguments& args)
{
return return
node::Script::EvalMachine<unwrapExternal, thisContext, returnResult>(args); node::Script::EvalMachine<unwrapExternal, thisContext, returnResult>(args);
} }
Handle<Value> Handle<Value> node::Script::RunInNewContext(const Arguments& args) {
node::Script::RunInNewContext(const Arguments& args) {
return return
node::Script::EvalMachine<unwrapExternal, newContext, returnResult>(args); node::Script::EvalMachine<unwrapExternal, newContext, returnResult>(args);
} }
Handle<Value> Handle<Value> node::Script::CompileRunInContext (const Arguments& args) {
node::Script::CompileRunInContext (const Arguments& args)
{
return return
node::Script::EvalMachine<compileCode, userContext, returnResult>(args); node::Script::EvalMachine<compileCode, userContext, returnResult>(args);
} }
Handle<Value> Handle<Value> node::Script::CompileRunInThisContext (const Arguments& args) {
node::Script::CompileRunInThisContext (const Arguments& args)
{
return return
node::Script::EvalMachine<compileCode, thisContext, returnResult>(args); node::Script::EvalMachine<compileCode, thisContext, returnResult>(args);
} }
Handle<Value> Handle<Value> node::Script::CompileRunInNewContext(const Arguments& args) {
node::Script::CompileRunInNewContext(const Arguments& args) {
return return
node::Script::EvalMachine<compileCode, newContext, returnResult>(args); node::Script::EvalMachine<compileCode, newContext, returnResult>(args);
} }
// Extracts a C str from a V8 Utf8Value.
const char* ToCString(const v8::String::Utf8Value& value) {
return *value ? *value : "<str conversion failed>";
}
template <node::Script::EvalInputFlags iFlag, template <node::Script::EvalInputFlags iFlag,
node::Script::EvalContextFlags cFlag, node::Script::EvalContextFlags cFlag,
node::Script::EvalOutputFlags oFlag> node::Script::EvalOutputFlags oFlag>
Handle<Value> node::Script::EvalMachine(const Arguments& args) { Handle<Value> node::Script::EvalMachine(const Arguments& args) {
HandleScope scope; HandleScope scope;
if (iFlag == compileCode && args.Length() < 1) { if (iFlag == compileCode && args.Length() < 1) {
return ThrowException(Exception::TypeError( return ThrowException(Exception::TypeError(
String::New("needs at least 'code' argument.") String::New("needs at least 'code' argument.")));
));
} }
const int sbIndex = iFlag == compileCode ? 1 : 0; const int sbIndex = iFlag == compileCode ? 1 : 0;
if (cFlag == userContext && args.Length() < (sbIndex + 1)) { if (cFlag == userContext && args.Length() < (sbIndex + 1)) {
return ThrowException(Exception::TypeError( return ThrowException(Exception::TypeError(
String::New("needs a 'context' argument.") String::New("needs a 'context' argument.")));
));
} }
Local<String> code; Local<String> code;
if (iFlag == compileCode) { code = args[0]->ToString(); } if (iFlag == compileCode) code = args[0]->ToString();
Local<Object> sandbox; Local<Object> sandbox;
if (cFlag == newContext) { if (cFlag == newContext) {
sandbox = args.Length() > sbIndex ? args[sbIndex]->ToObject() : Object::New(); sandbox = args.Length() > sbIndex ? args[sbIndex]->ToObject() : Object::New();
} } else if (cFlag == userContext) {
else if (cFlag == userContext) {
sandbox = args[sbIndex]->ToObject(); sandbox = args[sbIndex]->ToObject();
} }
const int fnIndex = sbIndex + (cFlag == newContext ? 1 : 0); const int fnIndex = sbIndex + (cFlag == newContext ? 1 : 0);
Local<String> filename = args.Length() > fnIndex ? args[fnIndex]->ToString() Local<String> filename = args.Length() > fnIndex
: String::New("evalmachine.<anonymous>"); ? args[fnIndex]->ToString()
: String::New("evalmachine.<anonymous>");
Persistent<v8::Context> context; Persistent<v8::Context> context;
Local<Array> keys; Local<Array> keys;
unsigned int i; unsigned int i;
if (cFlag == newContext) { if (cFlag == newContext) {
@ -218,7 +202,6 @@ Handle<Value> node::Script::EvalMachine(const Arguments& args) {
// New and user context share code. DRY it up. // New and user context share code. DRY it up.
if (cFlag == userContext || cFlag == newContext) { if (cFlag == userContext || cFlag == newContext) {
// Enter the context // Enter the context
context->Enter(); context->Enter();
@ -240,51 +223,48 @@ Handle<Value> node::Script::EvalMachine(const Arguments& args) {
Handle<v8::Script> script; Handle<v8::Script> script;
if (iFlag == compileCode) { if (iFlag == compileCode) {
// well, here node::Script::New would suffice in all cases, but maybe Compile has a little better performance where possible // well, here node::Script::New would suffice in all cases, but maybe
script = oFlag == returnResult ? v8::Script::Compile(code, filename) : v8::Script::New(code, filename); // Compile has a little better performance where possible
script = oFlag == returnResult ? v8::Script::Compile(code, filename)
: v8::Script::New(code, filename);
if (script.IsEmpty()) { if (script.IsEmpty()) {
// Hack because I can't get a proper stacktrace on SyntaxError // Hack because I can't get a proper stacktrace on SyntaxError
result = ThrowException(try_catch.Exception()); return try_catch.ReThrow();
} }
} else { } else {
node::Script *nScript = ObjectWrap::Unwrap<node::Script>(args.Holder()); node::Script *nScript = ObjectWrap::Unwrap<node::Script>(args.Holder());
if (!nScript) { if (!nScript) {
Local<Value> exception = return ThrowException(Exception::Error(
Exception::Error(String::New("Must be called as a method of Script.")); String::New("Must be called as a method of Script.")));
result = ThrowException(exception); } else if (nScript->script_.IsEmpty()) {
} else if (nScript->_script.IsEmpty()) { return ThrowException(Exception::Error(
Local<Value> exception = String::New("'this' must be a result of previous new Script(code) call.")));
Exception::Error(String::New("'this' must be a result of previous new Script(code) call."));
result = ThrowException(exception);
} else {
script = nScript->_script;
} }
script = nScript->script_;
} }
if (result.IsEmpty()) {
if (oFlag == returnResult) { if (oFlag == returnResult) {
result = script->Run(); result = script->Run();
} else { if (result.IsEmpty()) return try_catch.ReThrow();
node::Script *nScript = ObjectWrap::Unwrap<node::Script>(args.Holder()); } else {
if (!nScript) { node::Script *nScript = ObjectWrap::Unwrap<node::Script>(args.Holder());
Local<Value> exception = if (!nScript) {
Exception::Error(String::New("Must be called as a method of Script.")); return ThrowException(Exception::Error(
result = ThrowException(exception); String::New("Must be called as a method of Script.")));
} else { }
nScript->_script = Persistent<v8::Script>::New(script); nScript->script_ = Persistent<v8::Script>::New(script);
result = args.This(); result = args.This();
} }
}
if (result.IsEmpty()) { if (cFlag == userContext || cFlag == newContext) {
return try_catch.ReThrow(); // success! copy changes back onto the sandbox object.
} else if (cFlag == userContext || cFlag == newContext) { keys = context->Global()->GetPropertyNames();
// success! copy changes back onto the sandbox object. for (i = 0; i < keys->Length(); i++) {
keys = context->Global()->GetPropertyNames(); Handle<String> key = keys->Get(Integer::New(i))->ToString();
for (i = 0; i < keys->Length(); i++) { Handle<Value> value = context->Global()->Get(key);
Handle<String> key = keys->Get(Integer::New(i))->ToString(); sandbox->Set(key, value);
Handle<Value> value = context->Global()->Get(key);
sandbox->Set(key, value);
}
} }
} }

View File

@ -20,12 +20,13 @@ class Context : ObjectWrap {
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
Context () : ObjectWrap () {} Context ();
~Context(); ~Context();
v8::Persistent<v8::Context> _context; v8::Persistent<v8::Context> context_;
}; };
class Script : ObjectWrap { class Script : ObjectWrap {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize (v8::Handle<v8::Object> target);
@ -52,8 +53,9 @@ class Script : ObjectWrap {
static v8::Handle<v8::Value> CompileRunInThisContext (const v8::Arguments& args); static v8::Handle<v8::Value> CompileRunInThisContext (const v8::Arguments& args);
static v8::Handle<v8::Value> CompileRunInNewContext (const v8::Arguments& args); static v8::Handle<v8::Value> CompileRunInNewContext (const v8::Arguments& args);
v8::Persistent<v8::Script> _script; v8::Persistent<v8::Script> script_;
}; };
} // namespace node } // namespace node
#endif // node_script_h #endif // node_script_h