X Tutup
#include
#include
#include
using namespace v8; using namespace node; Persistent
node::Context::constructor_template; void node::Context::Initialize (Handle
target) { HandleScope scope; Local
t = FunctionTemplate::New(node::Context::New); constructor_template = Persistent
::New(t); constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("Context")); target->Set(String::NewSymbol("Context"), constructor_template->GetFunction()); } Handle
node::Context::New (const Arguments& args) { HandleScope scope; node::Context *t = new node::Context(); t->Wrap(args.This()); return args.This(); } node::Context::Context() : ObjectWrap() { context_ = v8::Context::New(); } node::Context::~Context() { context_.Dispose(); } Local
node::Context::NewInstance() { Local
context = constructor_template->GetFunction()->NewInstance(); return context; } v8::Persistent
node::Context::GetV8Context() { return context_; } Persistent
node::Script::constructor_template; void node::Script::Initialize (Handle
target) { HandleScope scope; Local
t = FunctionTemplate::New(node::Script::New); constructor_template = Persistent
::New(t); constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("Script")); NODE_SET_PROTOTYPE_METHOD(constructor_template, "createContext", node::Script::CreateContext); NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInContext", node::Script::RunInContext); NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInThisContext", node::Script::RunInThisContext); NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInNewContext", node::Script::RunInNewContext); NODE_SET_METHOD(constructor_template, "createContext", node::Script::CreateContext); NODE_SET_METHOD(constructor_template, "runInContext", node::Script::CompileRunInContext); NODE_SET_METHOD(constructor_template, "runInThisContext", node::Script::CompileRunInThisContext); NODE_SET_METHOD(constructor_template, "runInNewContext", node::Script::CompileRunInNewContext); target->Set(String::NewSymbol("Script"), constructor_template->GetFunction()); } Handle
node::Script::New (const Arguments& args) { HandleScope scope; node::Script *t = new node::Script(); t->Wrap(args.Holder()); return node::Script::EvalMachine
(args); } node::Script::~Script() { script_.Dispose(); } Handle
node::Script::CreateContext (const Arguments& args) { HandleScope scope; Local
context = node::Context::NewInstance(); if (args.Length() > 0) { Local
sandbox = args[0]->ToObject(); Local
keys = sandbox->GetPropertyNames(); for (int i = 0; i < keys->Length(); i++) { Handle
key = keys->Get(Integer::New(i))->ToString(); Handle
value = sandbox->Get(key); context->Set(key, value); } } return scope.Close(context); } Handle
node::Script::RunInContext (const Arguments& args) { return node::Script::EvalMachine
(args); } Handle
node::Script::RunInThisContext (const Arguments& args) { return node::Script::EvalMachine
(args); } Handle
node::Script::RunInNewContext(const Arguments& args) { return node::Script::EvalMachine
(args); } Handle
node::Script::CompileRunInContext (const Arguments& args) { return node::Script::EvalMachine
(args); } Handle
node::Script::CompileRunInThisContext (const Arguments& args) { return node::Script::EvalMachine
(args); } Handle
node::Script::CompileRunInNewContext(const Arguments& args) { return node::Script::EvalMachine
(args); } template
Handle
node::Script::EvalMachine(const Arguments& args) { HandleScope scope; if (iFlag == compileCode && args.Length() < 1) { return ThrowException(Exception::TypeError( String::New("needs at least 'code' argument."))); } const int sbIndex = iFlag == compileCode ? 1 : 0; if (cFlag == userContext && args.Length() < (sbIndex + 1)) { return ThrowException(Exception::TypeError( String::New("needs a 'context' argument."))); } Local
code; if (iFlag == compileCode) code = args[0]->ToString(); Local
sandbox; if (cFlag == newContext) { sandbox = args[sbIndex]->IsObject() ? args[sbIndex]->ToObject() : Object::New(); } else if (cFlag == userContext) { sandbox = args[sbIndex]->ToObject(); } const int fnIndex = sbIndex + (cFlag == newContext ? 1 : 0); Local
filename = args.Length() > fnIndex ? args[fnIndex]->ToString() : String::New("evalmachine.
"); Persistent
context; Local
keys; unsigned int i; if (cFlag == newContext) { // Create the new context context = v8::Context::New(); } else if (cFlag == userContext) { // Use the passed in context Local
contextArg = args[sbIndex]->ToObject(); node::Context *nContext = ObjectWrap::Unwrap
(sandbox); context = nContext->GetV8Context(); } // New and user context share code. DRY it up. if (cFlag == userContext || cFlag == newContext) { // Enter the context context->Enter(); // Copy everything from the passed in sandbox (either the persistent // context for runInContext(), or the sandbox arg to runInNewContext()). keys = sandbox->GetPropertyNames(); for (i = 0; i < keys->Length(); i++) { Handle
key = keys->Get(Integer::New(i))->ToString(); Handle
value = sandbox->Get(key); if (value == sandbox) { value = context->Global(); } context->Global()->Set(key, value); } } // Catch errors TryCatch try_catch; Handle
result; Handle
script; if (iFlag == compileCode) { // well, here node::Script::New would suffice in all cases, but maybe // Compile has a little better performance where possible script = oFlag == returnResult ? v8::Script::Compile(code, filename) : v8::Script::New(code, filename); if (script.IsEmpty()) { // Hack because I can't get a proper stacktrace on SyntaxError return try_catch.ReThrow(); } } else { node::Script *nScript = ObjectWrap::Unwrap
(args.Holder()); if (!nScript) { return ThrowException(Exception::Error( String::New("Must be called as a method of Script."))); } else if (nScript->script_.IsEmpty()) { return ThrowException(Exception::Error( String::New("'this' must be a result of previous new Script(code) call."))); } script = nScript->script_; } if (oFlag == returnResult) { result = script->Run(); if (result.IsEmpty()) return try_catch.ReThrow(); } else { node::Script *nScript = ObjectWrap::Unwrap
(args.Holder()); if (!nScript) { return ThrowException(Exception::Error( String::New("Must be called as a method of Script."))); } nScript->script_ = Persistent
::New(script); result = args.This(); } if (cFlag == userContext || cFlag == newContext) { // success! copy changes back onto the sandbox object. keys = context->Global()->GetPropertyNames(); for (i = 0; i < keys->Length(); i++) { Handle
key = keys->Get(Integer::New(i))->ToString(); Handle
value = context->Global()->Get(key); if (value == context->Global()) { value = sandbox; } sandbox->Set(key, value); } } if (cFlag == newContext) { // Clean up, clean up, everybody everywhere! context->DetachGlobal(); context->Exit(); context.Dispose(); } else if (cFlag == userContext) { // Exit the passed in context. context->Exit(); } return result == args.This() ? result : scope.Close(result); } void node::InitEvals(Handle
target) { HandleScope scope; node::Context::Initialize(target); node::Script::Initialize(target); } NODE_MODULE(node_evals, node::InitEvals);
X Tutup