From 560df7e5f37598131e64fe678d8e83b69372fe14 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 9 Apr 2016 15:24:48 +0000 Subject: [PATCH] Made it possible to require() a script from another package. It's high time for some code reuse. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3191 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/core.js | 10 ++++++++++ src/Task.cpp | 39 +++++++++++++++++++++++++++++++++++---- src/Task.h | 2 ++ src/TaskStub.cpp | 9 +++++++++ src/TaskStub.h | 2 ++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/core/core.js b/core/core.js index f263c8fe..b42db1e0 100644 --- a/core/core.js +++ b/core/core.js @@ -215,6 +215,11 @@ function getManifest(fileName) { return manifest.length ? JSON.parse(manifest.join("\n")) : null; } +function packageNameToPath(name) { + var process = this; + return "packages/" + process.packageOwner + "/" + name + "/"; +} + function getProcess(packageOwner, packageName, key, options) { var process = gProcesses[key]; if (!process @@ -342,6 +347,11 @@ function getProcess(packageOwner, packageName, key, options) { throw new Error(packageOwner + " does not have right to permission 'network'."); } } + if (manifest && manifest.require) { + print("manifest.require = ", manifest.require); + print(manifest.require.map(packageNameToPath.bind(process))); + process.task.addPath(manifest.require.map(packageNameToPath.bind(process))); + } process.task.setImports(imports); print("Activating task"); process.task.activate(); diff --git a/src/Task.cpp b/src/Task.cpp index 91cf712a..9eced356 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -182,6 +182,11 @@ void Task::activate() { v8::Local context = v8::Context::New(_isolate, 0, global); _context = v8::Persistent >(_isolate, context); + + v8::Context::Scope contextScope(v8::Local::New(_isolate, _context)); + + v8::Local exportObject = v8::Object::New(_isolate); + _exportObject = v8::Persistent >(_isolate, exportObject); } void Task::activate(const v8::FunctionCallbackInfo& args) { @@ -270,6 +275,16 @@ bool Task::execute(const char* fileName) { if (!_scriptName.size()) { _scriptName = fileName; } + if (!_path.size()) { + std::string path = _scriptName; + size_t position = path.rfind('/'); + if (position != std::string::npos) { + path.resize(position + 1); + } else { + path = "."; + } + _path.push_back(path); + } if (!source.IsEmpty()) { v8::Handle script = v8::Script::Compile(source, name); if (!script.IsEmpty()) { @@ -645,6 +660,23 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi to->_trusted = trusted; } break; + case kAddPath: + { + v8::Handle result = v8::Handle::Cast(Serialize::load(to, from, std::vector(begin, begin + length))); + if (!result.IsEmpty()) { + for (size_t i = 0; i < result->Length(); ++i) { + v8::Handle handle = result->Get(i); + if (!handle.IsEmpty()) { + v8::Handle entry = handle.As(); + if (!entry.IsEmpty()) { + v8::String::Utf8Value value(entry); + to->_path.push_back(*value); + } + } + } + } + } + break; case kActivate: to->activate(); break; @@ -692,10 +724,9 @@ void Task::configureFromStdin() { std::string Task::resolveRequire(const std::string& require) { std::string result; - std::string path = _scriptName; - size_t position = path.rfind('/'); - if (position != std::string::npos) { - path.resize(position + 1); + + for (size_t i = 0; i < _path.size(); ++i) { + std::string& path = _path[i]; std::cout << "Looking in " << path << " for " << require << "\n"; if (require.find("..") == std::string::npos && require.find('/') == std::string::npos) { result = path + require; diff --git a/src/Task.h b/src/Task.h index 8bb7b486..e6a48568 100644 --- a/src/Task.h +++ b/src/Task.h @@ -31,6 +31,7 @@ enum MessageType { kReleaseExport, kReleaseImport, kSetTrusted, + kAddPath, kActivate, kExecute, kKill, @@ -95,6 +96,7 @@ private: taskid_t _nextTask = 1; static const taskid_t kParentId = 0; std::map _children; + std::vector _path; typedef std::map > > ScriptExportMap; ScriptExportMap _scriptExports; diff --git a/src/TaskStub.cpp b/src/TaskStub.cpp index 80e07bc1..350024c2 100644 --- a/src/TaskStub.cpp +++ b/src/TaskStub.cpp @@ -91,6 +91,7 @@ void TaskStub::create(const v8::FunctionCallbackInfo& args) { taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "execute"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::execute, data)); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "kill"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::kill, data)); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "statistics"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::statistics, data)); + taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "addPath"), v8::FunctionTemplate::New(args.GetIsolate(), addPath, data)); taskTemplate->SetInternalFieldCount(1); v8::Handle taskObject = taskTemplate->NewInstance(); @@ -195,6 +196,14 @@ void TaskStub::setImports(const v8::FunctionCallbackInfo& args) { } } +void TaskStub::addPath(const v8::FunctionCallbackInfo& args) { + if (TaskStub* stub = TaskStub::get(args.Data())) { + std::vector buffer; + Serialize::store(Task::get(args.GetIsolate()), buffer, args[0]); + stub->_stream.send(kAddPath, &*buffer.begin(), buffer.size()); + } +} + void TaskStub::getOnExit(v8::Local property, const v8::PropertyCallbackInfo& args) { TaskTryCatch tryCatch(TaskStub::get(args.Data())->_owner); v8::HandleScope scope(args.GetIsolate()); diff --git a/src/TaskStub.h b/src/TaskStub.h index 9a8ed64e..ec581367 100644 --- a/src/TaskStub.h +++ b/src/TaskStub.h @@ -47,6 +47,8 @@ private: static void getExports(const v8::FunctionCallbackInfo& args); static void setImports(const v8::FunctionCallbackInfo& args); + static void addPath(const v8::FunctionCallbackInfo& args); + static void getOnExit(v8::Local property, const v8::PropertyCallbackInfo& args); static void setOnExit(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& args);