forked from cory/tildefriends
		
	Now child processes have no ability to open files.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3206 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		@@ -328,13 +328,18 @@ function getProcess(packageOwner, packageName, key, options) {
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (manifest && manifest.require) {
 | 
			
		||||
				process.task.addPath(manifest.require.map(packageNameToPath.bind(process)));
 | 
			
		||||
				let source = {};
 | 
			
		||||
				for (let i in manifest.require) {
 | 
			
		||||
					let name = manifest.require[i];
 | 
			
		||||
					source[manifest[i]] = File.readFile("packages/" + process.packageOwner + "/" + name + "/" + name + ".js");
 | 
			
		||||
				}
 | 
			
		||||
				process.task.setRequires(source);
 | 
			
		||||
			}
 | 
			
		||||
			process.task.setImports(imports);
 | 
			
		||||
			print("Activating task");
 | 
			
		||||
			process.task.activate();
 | 
			
		||||
			print("Executing task");
 | 
			
		||||
			process.task.execute(fileName).then(function() {
 | 
			
		||||
			process.task.execute({name: fileName, source: File.readFile(fileName)}).then(function() {
 | 
			
		||||
				print("Task ready");
 | 
			
		||||
				broadcastEvent('onSessionBegin', [getUser(process, process)]);
 | 
			
		||||
				resolveReady(process);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								src/Task.cpp
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								src/Task.cpp
									
									
									
									
									
								
							@@ -105,6 +105,7 @@ Task::Task() {
 | 
			
		||||
 | 
			
		||||
Task::~Task() {
 | 
			
		||||
	_exportObject.Reset();
 | 
			
		||||
	_sourceObject.Reset();
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		v8::Isolate::Scope isolateScope(_isolate);
 | 
			
		||||
@@ -166,7 +167,6 @@ void Task::activate() {
 | 
			
		||||
 | 
			
		||||
	global->Set(v8::String::NewFromUtf8(_isolate, "print"), v8::FunctionTemplate::New(_isolate, print));
 | 
			
		||||
	global->Set(v8::String::NewFromUtf8(_isolate, "setTimeout"), v8::FunctionTemplate::New(_isolate, setTimeout));
 | 
			
		||||
	global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, require));
 | 
			
		||||
	global->SetAccessor(v8::String::NewFromUtf8(_isolate, "parent"), parent);
 | 
			
		||||
	global->Set(v8::String::NewFromUtf8(_isolate, "exit"), v8::FunctionTemplate::New(_isolate, exit));
 | 
			
		||||
	global->Set(v8::String::NewFromUtf8(_isolate, "utf8Length"), v8::FunctionTemplate::New(_isolate, utf8Length));
 | 
			
		||||
@@ -175,11 +175,16 @@ void Task::activate() {
 | 
			
		||||
	global->SetAccessor(v8::String::NewFromUtf8(_isolate, "version"), version);
 | 
			
		||||
	global->SetAccessor(v8::String::NewFromUtf8(_isolate, "statistics"), statistics);
 | 
			
		||||
	if (_trusted) {
 | 
			
		||||
		std::cout << "parent require\n";
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, require));
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "Database"), v8::FunctionTemplate::New(_isolate, Database::create));
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "Socket"), v8::FunctionTemplate::New(_isolate, Socket::create));
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "Task"), v8::FunctionTemplate::New(_isolate, TaskStub::create));
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "TlsContext"), v8::FunctionTemplate::New(_isolate, TlsContextWrapper::create));
 | 
			
		||||
		File::configure(_isolate, global);
 | 
			
		||||
	} else {
 | 
			
		||||
		std::cout << "setting up child require\n";
 | 
			
		||||
		global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, childRequire));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v8::Local<v8::Context> context = v8::Context::New(_isolate, 0, global);
 | 
			
		||||
@@ -654,29 +659,10 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case kSetTrusted:
 | 
			
		||||
	case kSetRequires:
 | 
			
		||||
		{
 | 
			
		||||
			assert(length == sizeof(bool));
 | 
			
		||||
			bool trusted = false;
 | 
			
		||||
			memcpy(&trusted, begin, sizeof(bool));
 | 
			
		||||
			to->_trusted = trusted;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case kAddPath:
 | 
			
		||||
		{
 | 
			
		||||
			v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(Serialize::load(to, from, std::vector<char>(begin, begin + length)));
 | 
			
		||||
			if (!result.IsEmpty()) {
 | 
			
		||||
				for (size_t i = 0; i < result->Length(); ++i) {
 | 
			
		||||
					v8::Handle<v8::Value> handle = result->Get(i);
 | 
			
		||||
					if (!handle.IsEmpty()) {
 | 
			
		||||
						v8::Handle<v8::String> entry = handle.As<v8::String>();
 | 
			
		||||
						if (!entry.IsEmpty()) {
 | 
			
		||||
							v8::String::Utf8Value value(entry);
 | 
			
		||||
							to->_path.push_back(*value);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			v8::Handle<v8::Object> result = v8::Handle<v8::Object>::Cast(Serialize::load(to, from, std::vector<char>(begin, begin + length)));
 | 
			
		||||
			to->_sourceObject = v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> >(to->_isolate, result);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case kActivate:
 | 
			
		||||
@@ -685,14 +671,16 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi
 | 
			
		||||
	case kExecute:
 | 
			
		||||
		{
 | 
			
		||||
			assert(length >= sizeof(promiseid_t));
 | 
			
		||||
			v8::Handle<v8::Value> arg;
 | 
			
		||||
			promiseid_t promise;
 | 
			
		||||
			std::memcpy(&promise, begin, sizeof(promiseid_t));
 | 
			
		||||
			arg = Serialize::load(to, from, std::vector<char>(begin + sizeof(promiseid_t), begin + length));
 | 
			
		||||
			v8::TryCatch tryCatch(to->_isolate);
 | 
			
		||||
			tryCatch.SetCaptureMessage(true);
 | 
			
		||||
			tryCatch.SetVerbose(true);
 | 
			
		||||
			to->execute(*v8::String::Utf8Value(arg));
 | 
			
		||||
			v8::Handle<v8::Value> value = Serialize::load(to, from, std::vector<char>(begin + sizeof(promiseid_t), begin + length));
 | 
			
		||||
			v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
 | 
			
		||||
			v8::Handle<v8::String> source = v8::Handle<v8::String>::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "source")));
 | 
			
		||||
			v8::Handle<v8::String> name = v8::Handle<v8::String>::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "name")));
 | 
			
		||||
			to->executeSource(source, name);
 | 
			
		||||
			if (tryCatch.HasCaught()) {
 | 
			
		||||
				sendPromiseReject(to, from, promise, Serialize::store(to, tryCatch));
 | 
			
		||||
			}
 | 
			
		||||
@@ -746,6 +734,7 @@ std::string Task::resolveRequire(const std::string& require) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Task::require(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	std::cout << "regular require\n";
 | 
			
		||||
	v8::HandleScope scope(args.GetIsolate());
 | 
			
		||||
	Task* task = Task::get(args.GetIsolate());
 | 
			
		||||
	v8::String::Utf8Value pathValue(args[0]);
 | 
			
		||||
@@ -788,3 +777,58 @@ void Task::require(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
		args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), "require(): No module specified."))));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v8::Handle<v8::Value> Task::executeSource(v8::Handle<v8::String>& source, v8::Handle<v8::String>& name) {
 | 
			
		||||
	v8::Isolate::Scope isolateScope(_isolate);
 | 
			
		||||
	v8::HandleScope handleScope(_isolate);
 | 
			
		||||
	v8::Context::Scope contextScope(v8::Local<v8::Context>::New(_isolate, _context));
 | 
			
		||||
 | 
			
		||||
	v8::Handle<v8::Value> result;
 | 
			
		||||
	v8::String::Utf8Value nameValue(name);
 | 
			
		||||
	if (!source.IsEmpty()) {
 | 
			
		||||
		v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
 | 
			
		||||
		if (!script.IsEmpty()) {
 | 
			
		||||
			script->Run();
 | 
			
		||||
		} else {
 | 
			
		||||
			result = _isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(_isolate, (std::string("Failed to compile ") + *nameValue + ".").c_str())));
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		result = _isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(_isolate, (std::string("Failed to load ") + *nameValue + ".").c_str())));
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Task::childRequire(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	std::cout << "childRequire\n";
 | 
			
		||||
	v8::HandleScope scope(args.GetIsolate());
 | 
			
		||||
	Task* task = Task::get(args.GetIsolate());
 | 
			
		||||
 | 
			
		||||
	v8::Handle<v8::Object> requiresObject = v8::Local<v8::Object>::New(args.GetIsolate(), task->_sourceObject);
 | 
			
		||||
	if (!requiresObject.IsEmpty()) {
 | 
			
		||||
		v8::Handle<v8::String> name = args[0]->ToString();
 | 
			
		||||
		v8::String::Utf8Value nameValue(name);
 | 
			
		||||
		ScriptExportMap::iterator it = task->_scriptExports.find(*nameValue);
 | 
			
		||||
		if (it != task->_scriptExports.end()) {
 | 
			
		||||
			v8::Handle<v8::Object> exports = v8::Local<v8::Object>::New(args.GetIsolate(), it->second);
 | 
			
		||||
			args.GetReturnValue().Set(exports);
 | 
			
		||||
		} else {
 | 
			
		||||
			v8::Handle<v8::Object> exports = v8::Object::New(args.GetIsolate());
 | 
			
		||||
			v8::Handle<v8::String> source = v8::Handle<v8::String>::Cast(requiresObject->Get(args[0]));
 | 
			
		||||
			if (!source.IsEmpty()) {
 | 
			
		||||
				v8::Handle<v8::Object> global = args.GetIsolate()->GetCurrentContext()->Global();
 | 
			
		||||
				v8::Handle<v8::Value> oldExports = global->Get(v8::String::NewFromUtf8(args.GetIsolate(), "exports"));
 | 
			
		||||
				global->Set(v8::String::NewFromUtf8(args.GetIsolate(), "exports"), exports);
 | 
			
		||||
				v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
 | 
			
		||||
				if (!script.IsEmpty()) {
 | 
			
		||||
					script->Run();
 | 
			
		||||
				} else {
 | 
			
		||||
					args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), (std::string("Failed to compile ") + *nameValue + ".").c_str()))));
 | 
			
		||||
				}
 | 
			
		||||
				global->Set(v8::String::NewFromUtf8(args.GetIsolate(), "exports"), oldExports);
 | 
			
		||||
				args.GetReturnValue().Set(exports);
 | 
			
		||||
			} else {
 | 
			
		||||
				args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), (std::string("Failed to load ") + *nameValue + ".").c_str()))));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,7 @@ enum MessageType {
 | 
			
		||||
	kInvokeExport,
 | 
			
		||||
	kReleaseExport,
 | 
			
		||||
	kReleaseImport,
 | 
			
		||||
	kSetTrusted,
 | 
			
		||||
	kAddPath,
 | 
			
		||||
	kSetRequires,
 | 
			
		||||
	kActivate,
 | 
			
		||||
	kExecute,
 | 
			
		||||
	kKill,
 | 
			
		||||
@@ -120,6 +119,7 @@ private:
 | 
			
		||||
 | 
			
		||||
	v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _importObject;
 | 
			
		||||
	v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _exportObject;
 | 
			
		||||
	v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _sourceObject;
 | 
			
		||||
 | 
			
		||||
	v8::Handle<v8::Object> getStatistics();
 | 
			
		||||
 | 
			
		||||
@@ -129,6 +129,7 @@ private:
 | 
			
		||||
	static void exit(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void print(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void require(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void childRequire(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
 | 
			
		||||
	static void setTimeout(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void timeoutCallback(uv_timer_t* handle);
 | 
			
		||||
@@ -157,6 +158,7 @@ private:
 | 
			
		||||
	static void sendPromiseExportMessage(Task* from, TaskStub* to, MessageType messageType, promiseid_t promiseId, exportid_t exportId, v8::Handle<v8::Value> result);
 | 
			
		||||
 | 
			
		||||
	static v8::Handle<v8::String> loadFile(v8::Isolate* isolate, const char* fileName);
 | 
			
		||||
	v8::Handle<v8::Value> executeSource(v8::Handle<v8::String>& source, v8::Handle<v8::String>& name);
 | 
			
		||||
 | 
			
		||||
	friend struct ImportRecord;
 | 
			
		||||
	friend class TaskStub;
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,6 @@ void TaskStub::create(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	v8::Handle<v8::External> data = v8::External::New(args.GetIsolate(), stub);
 | 
			
		||||
 | 
			
		||||
	v8::Handle<v8::ObjectTemplate> taskTemplate = v8::ObjectTemplate::New(args.GetIsolate());
 | 
			
		||||
	taskTemplate->SetAccessor(v8::String::NewFromUtf8(args.GetIsolate(), "trusted"), getTrusted, setTrusted, data);
 | 
			
		||||
	taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "setImports"), v8::FunctionTemplate::New(args.GetIsolate(), setImports, data));
 | 
			
		||||
	taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "getExports"), v8::FunctionTemplate::New(args.GetIsolate(), getExports, data));
 | 
			
		||||
	taskTemplate->SetAccessor(v8::String::NewFromUtf8(args.GetIsolate(), "onExit"), getOnExit, setOnExit, data);
 | 
			
		||||
@@ -91,7 +90,7 @@ void TaskStub::create(const v8::FunctionCallbackInfo<v8::Value>& 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->Set(v8::String::NewFromUtf8(args.GetIsolate(), "setRequires"), v8::FunctionTemplate::New(args.GetIsolate(), setRequires, data));
 | 
			
		||||
	taskTemplate->SetInternalFieldCount(1);
 | 
			
		||||
 | 
			
		||||
	v8::Handle<v8::Object> taskObject = taskTemplate->NewInstance();
 | 
			
		||||
@@ -166,17 +165,6 @@ void TaskStub::onProcessExit(uv_process_t* process, int64_t status, int terminat
 | 
			
		||||
void TaskStub::onRelease(const v8::WeakCallbackData<v8::Object, TaskStub>& data) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TaskStub::getTrusted(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), false));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TaskStub::setTrusted(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args) {
 | 
			
		||||
	if (TaskStub* stub = TaskStub::get(args.Data())) {
 | 
			
		||||
		bool trusted = value->BooleanValue();
 | 
			
		||||
		stub->_stream.send(kSetTrusted, reinterpret_cast<char*>(&trusted), sizeof(trusted));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TaskStub::getExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	if (TaskStub* stub = TaskStub::get(args.Data())) {
 | 
			
		||||
		TaskTryCatch tryCatch(stub->_owner);
 | 
			
		||||
@@ -196,11 +184,11 @@ void TaskStub::setImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TaskStub::addPath(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
void TaskStub::setRequires(const v8::FunctionCallbackInfo<v8::Value>& args) {
 | 
			
		||||
	if (TaskStub* stub = TaskStub::get(args.Data())) {
 | 
			
		||||
		std::vector<char> buffer;
 | 
			
		||||
		Serialize::store(Task::get(args.GetIsolate()), buffer, args[0]);
 | 
			
		||||
		stub->_stream.send(kAddPath, &*buffer.begin(), buffer.size());
 | 
			
		||||
		stub->_stream.send(kSetRequires, &*buffer.begin(), buffer.size());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,13 +41,10 @@ private:
 | 
			
		||||
 | 
			
		||||
	static TaskStub* get(v8::Handle<v8::Value> object);
 | 
			
		||||
 | 
			
		||||
	static void getTrusted(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void setTrusted(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
 | 
			
		||||
 | 
			
		||||
	static void getExports(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void setImports(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
 | 
			
		||||
	static void addPath(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void setRequires(const v8::FunctionCallbackInfo<v8::Value>& args);
 | 
			
		||||
 | 
			
		||||
	static void getOnExit(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
 | 
			
		||||
	static void setOnExit(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
 | 
			
		||||
 
 | 
			
		||||
@@ -43,12 +43,9 @@ void shedPrivileges() {
 | 
			
		||||
	if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) {
 | 
			
		||||
		perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})");
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	XXX
 | 
			
		||||
	if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) {
 | 
			
		||||
		perror("setrlimit(RLIMIT_NOFILE, {0, 0})");
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
	if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) {
 | 
			
		||||
		perror("setrlimit(RLIMIT_NPROC, {0, 0})");
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ task.onExit = function() {
 | 
			
		||||
	print("child exited");
 | 
			
		||||
};
 | 
			
		||||
task.activate();
 | 
			
		||||
task.execute("child.js").then(function() {
 | 
			
		||||
task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() {
 | 
			
		||||
	print("child started");
 | 
			
		||||
});
 | 
			
		||||
EOF
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
cat > test.js << EOF
 | 
			
		||||
var task = new Task();
 | 
			
		||||
task.activate();
 | 
			
		||||
task.execute("child.js").then(function() {
 | 
			
		||||
task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() {
 | 
			
		||||
	task.getExports().then(function(exports) {
 | 
			
		||||
		return exports.add(1, 1);
 | 
			
		||||
	}).then(function(sum) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
cat > test.js << EOF
 | 
			
		||||
var task = new Task();
 | 
			
		||||
task.activate();
 | 
			
		||||
task.execute("child.js").then(function() {
 | 
			
		||||
task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() {
 | 
			
		||||
	task.getExports().then(function(exports) {
 | 
			
		||||
		return exports.add(1, 1);
 | 
			
		||||
	}).then(function(sum) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
cat > test.js << EOF
 | 
			
		||||
var task = new Task();
 | 
			
		||||
task.activate();
 | 
			
		||||
task.execute("child.js").then(function() {
 | 
			
		||||
task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() {
 | 
			
		||||
	task.getExports().then(function(exports) {
 | 
			
		||||
		return exports.add(1, 1);
 | 
			
		||||
	}).then(function(sum) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user