Index: src/FileSystemJsObject.cpp |
=================================================================== |
--- a/src/FileSystemJsObject.cpp |
+++ b/src/FileSystemJsObject.cpp |
@@ -23,47 +23,40 @@ |
#include <AdblockPlus/JsValue.h> |
#include "FileSystemJsObject.h" |
#include "JsContext.h" |
+#include "JsEngineTransition.h" |
#include "Scheduler.h" |
#include "Utils.h" |
+#include "Value.h" |
using namespace AdblockPlus; |
namespace |
{ |
- class IoTask |
+ class ReadTask |
{ |
- protected: |
- virtual void operator()() = 0; |
+ /** |
+ * Shared pointer keeps engine in existence for task thread. |
+ */ |
JsEnginePtr jsEngine; |
- FileSystemPtr fileSystem; |
- JsValuePtr callback; |
+ std::string path; |
+ V8PersistentNG<v8::Function> callbackFunction; |
public: |
- IoTask(JsEnginePtr jsEngine, JsValuePtr callback) |
- : jsEngine(jsEngine), fileSystem(jsEngine->GetFileSystem()), |
- callback(callback) |
- { |
- } |
- |
- virtual ~IoTask() {} |
- }; |
- |
- class ReadTask : public IoTask |
- { |
- public: |
- ReadTask(JsEnginePtr jsEngine, JsValuePtr callback, |
- const std::string& path) |
- : IoTask(jsEngine, callback), path(path) |
- { |
- } |
+ ReadTask(JsEngineInternal* engine, const std::string& path, |
+ V8PersistentNG<v8::Function> callbackFunction) |
+ : jsEngine(engine->shared_from_this()), path(path), |
+ callbackFunction(callbackFunction) |
+ {} |
void operator()() |
{ |
+ JsEngineInternal* engine = ToInternal(jsEngine); |
std::string content; |
std::string error; |
+ // Read operation is long-lived. Do not lock engine during it. |
try |
{ |
- std::shared_ptr<std::istream> stream = fileSystem->Read(path); |
+ std::shared_ptr<std::istream> stream = engine->GetFileSystem()->Read(path); |
content = Utils::Slurp(*stream); |
} |
catch (std::exception& e) |
@@ -72,39 +65,46 @@ |
} |
catch (...) |
{ |
- error = "Unknown error while reading from " + path; |
+ error = "Unknown error while reading from " + path; |
} |
- |
- const JsContext context(jsEngine); |
- JsValuePtr result = jsEngine->NewObject(); |
- result->SetProperty("content", content); |
- result->SetProperty("error", error); |
- JsValueList params; |
- params.push_back(result); |
- callback->Call(params); |
+ // Call back with the results of the read operation |
+ V8ExecutionScope scope(engine); |
+ auto callbackArguments = v8::Object::New(); |
+ callbackArguments->Set(engine->ToV8String("content"), engine->ToV8String(content)); |
+ callbackArguments->Set(engine->ToV8String("error"), engine->ToV8String(error)); |
+ auto args = AllocatedArray<v8::Local<v8::Value>>(1); |
+ args[0] = callbackArguments; |
+ engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::move(args)); |
} |
- |
- private: |
- std::string path; |
}; |
- class WriteTask : public IoTask |
+ class WriteTask |
{ |
+ /** |
+ * Shared pointer keeps engine in existence for task thread. |
+ */ |
+ JsEnginePtr jsEngine; |
+ std::string path; |
+ std::string content; |
+ V8PersistentNG<v8::Function> callbackFunction; |
public: |
- WriteTask(JsEnginePtr jsEngine, JsValuePtr callback, |
- const std::string& path, const std::string& content) |
- : IoTask(jsEngine, callback), path(path), content(content) |
- { |
- } |
+ WriteTask(JsEngineInternal* engine, |
+ const std::string& path, const std::string& content, |
+ V8PersistentNG<v8::Function> callbackFunction) |
+ : jsEngine(engine->shared_from_this()), path(path), content(content), |
+ callbackFunction(callbackFunction) |
+ {} |
void operator()() |
{ |
+ JsEngineInternal* engine = ToInternal(jsEngine); |
std::string error; |
+ // Write operation is long-lived. Do not lock engine during it. |
try |
{ |
std::shared_ptr<std::iostream> stream(new std::stringstream); |
*stream << content; |
- fileSystem->Write(path, stream); |
+ engine->GetFileSystem()->Write(path, stream); |
} |
catch (std::exception& e) |
{ |
@@ -114,34 +114,38 @@ |
{ |
error = "Unknown error while writing to " + path; |
} |
- |
- const JsContext context(jsEngine); |
- JsValuePtr errorValue = jsEngine->NewValue(error); |
- JsValueList params; |
- params.push_back(errorValue); |
- callback->Call(params); |
+ // Apply the callback function |
+ V8ExecutionScope scope(engine); |
+ auto args = AllocatedArray<v8::Local<v8::Value>>(1); |
+ args[0] = engine->ToV8String(error); |
+ engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::move(args)); |
} |
- |
- private: |
- std::string path; |
- std::string content; |
}; |
- class MoveTask : public IoTask |
+ class MoveTask |
{ |
+ /** |
+ * Shared pointer keeps engine in existence for task thread. |
+ */ |
+ JsEnginePtr jsEngine; |
+ std::string fromPath; |
+ std::string toPath; |
+ V8PersistentNG<v8::Function> callbackFunction; |
+ |
public: |
- MoveTask(JsEnginePtr jsEngine, JsValuePtr callback, |
- const std::string& fromPath, const std::string& toPath) |
- : IoTask(jsEngine, callback), fromPath(fromPath), toPath(toPath) |
- { |
- } |
+ MoveTask(JsEngineInternal* engine, const std::string& fromPath, const std::string& toPath, |
+ V8PersistentNG<v8::Function> callbackFunction) |
+ : jsEngine(engine->shared_from_this()), fromPath(fromPath), toPath(toPath), |
+ callbackFunction(callbackFunction) |
+ {} |
void operator()() |
{ |
+ JsEngineInternal* engine(ToInternal(jsEngine)); |
std::string error; |
try |
{ |
- fileSystem->Move(fromPath, toPath); |
+ engine->GetFileSystem()->Move(fromPath, toPath); |
} |
catch (std::exception& e) |
{ |
@@ -151,34 +155,36 @@ |
{ |
error = "Unknown error while moving " + fromPath + " to " + toPath; |
} |
- |
- const JsContext context(jsEngine); |
- JsValuePtr errorValue = jsEngine->NewValue(error); |
- JsValueList params; |
- params.push_back(errorValue); |
- callback->Call(params); |
+ V8ExecutionScope scope(engine); |
+ auto args = AllocatedArray<v8::Local<v8::Value>>(1); |
+ args[0] = engine->ToV8String(error); |
+ engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::move(args)); |
} |
- |
- private: |
- std::string fromPath; |
- std::string toPath; |
}; |
- class RemoveTask : public IoTask |
+ class RemoveTask |
{ |
+ /** |
+ * Shared pointer keeps engine in existence for task thread. |
+ */ |
+ JsEnginePtr jsEngine; |
+ std::string path; |
+ V8PersistentNG<v8::Function> callbackFunction; |
+ |
public: |
- RemoveTask(JsEnginePtr jsEngine, JsValuePtr callback, |
- const std::string& path) |
- : IoTask(jsEngine, callback), path(path) |
- { |
- } |
+ RemoveTask(JsEngineInternal *engine, const std::string& path, |
+ V8PersistentNG<v8::Function> callbackFunction) |
+ : jsEngine(engine->shared_from_this()), path(path), |
+ callbackFunction(callbackFunction) |
+ {} |
void operator()() |
{ |
+ JsEngineInternal* engine(ToInternal(jsEngine)); |
std::string error; |
try |
{ |
- fileSystem->Remove(path); |
+ engine->GetFileSystem()->Remove(path); |
} |
catch (std::exception& e) |
{ |
@@ -188,35 +194,37 @@ |
{ |
error = "Unknown error while removing " + path; |
} |
- |
- const JsContext context(jsEngine); |
- JsValuePtr errorValue = jsEngine->NewValue(error); |
- JsValueList params; |
- params.push_back(errorValue); |
- callback->Call(params); |
+ V8ExecutionScope scope(engine); |
+ auto args = AllocatedArray<v8::Local<v8::Value>>(1); |
+ args[0] = engine->ToV8String(error); |
+ engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::move(args)); |
} |
- |
- private: |
- std::string path; |
}; |
+ class StatTask |
+ { |
+ /** |
+ * Shared pointer keeps engine in existence for task thread. |
+ */ |
+ JsEnginePtr jsEngine; |
+ std::string path; |
+ V8PersistentNG<v8::Function> callbackFunction; |
- class StatTask : public IoTask |
- { |
public: |
- StatTask(JsEnginePtr jsEngine, JsValuePtr callback, |
- const std::string& path) |
- : IoTask(jsEngine, callback), path(path) |
- { |
- } |
+ StatTask(JsEngineInternal* engine, const std::string& path, |
+ V8PersistentNG<v8::Function> callbackFunction) |
+ : jsEngine(engine->shared_from_this()), path(path), |
+ callbackFunction(callbackFunction) |
+ {} |
void operator()() |
{ |
+ JsEngineInternal* engine(ToInternal(jsEngine)); |
std::string error; |
FileSystem::StatResult statResult; |
try |
{ |
- statResult = fileSystem->Stat(path); |
+ statResult = engine->GetFileSystem()->Stat(path); |
} |
catch (std::exception& e) |
{ |
@@ -226,139 +234,221 @@ |
{ |
error = "Unknown error while calling stat on " + path; |
} |
- |
- const JsContext context(jsEngine); |
- JsValuePtr result = jsEngine->NewObject(); |
- result->SetProperty("exists", statResult.exists); |
- result->SetProperty("isFile", statResult.isFile); |
- result->SetProperty("isDirectory", statResult.isDirectory); |
- result->SetProperty("lastModified", statResult.lastModified); |
- result->SetProperty("error", error); |
- |
- JsValueList params; |
- params.push_back(result); |
- callback->Call(params); |
+ V8ExecutionScope scope(engine); |
+ auto callbackArgument(v8::Object::New()); |
+ callbackArgument->Set(engine->ToV8String("exists"), v8::Boolean::New(statResult.exists)); |
+ callbackArgument->Set(engine->ToV8String("isFile"), v8::Boolean::New(statResult.isFile)); |
+ callbackArgument->Set(engine->ToV8String("isDirectory"), v8::Boolean::New(statResult.isDirectory)); |
+ callbackArgument->Set(engine->ToV8String("lastModified"), v8::Number::New(statResult.lastModified)); |
+ callbackArgument->Set(engine->ToV8String("error"), engine->ToV8String(error)); |
+ auto args = AllocatedArray<v8::Local<v8::Value>>(1); |
+ args[0] = callbackArgument; |
+ engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::move(args)); |
} |
- |
- private: |
- std::string path; |
}; |
- |
- v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 2) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.read requires 2 parameters")); |
- if (!converted[1]->IsFunction()) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "Second argument to _fileSystem.read must be a function")); |
- const auto readTask = std::make_shared<ReadTask>(jsEngine, converted[1], |
- converted[0]->AsString()); |
- jsEngine->Schedule(AdblockPlus::MakeHeapFunction(readTask), AdblockPlus::ImmediateSingleUseThread); |
- return v8::Undefined(); |
- } |
- |
- v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 3) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.write requires 3 parameters")); |
- if (!converted[2]->IsFunction()) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "Third argument to _fileSystem.write must be a function")); |
- const auto writeTask = std::make_shared<WriteTask>(jsEngine, converted[2], |
- converted[0]->AsString(), converted[1]->AsString()); |
- jsEngine->Schedule(AdblockPlus::MakeHeapFunction(writeTask), AdblockPlus::ImmediateSingleUseThread); |
- return v8::Undefined(); |
- } |
- |
- v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 3) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.move requires 3 parameters")); |
- if (!converted[2]->IsFunction()) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "Third argument to _fileSystem.move must be a function")); |
- const auto moveTask = std::make_shared<MoveTask>(jsEngine, converted[2], |
- converted[0]->AsString(), converted[1]->AsString()); |
- jsEngine->Schedule(AdblockPlus::MakeHeapFunction(moveTask), AdblockPlus::ImmediateSingleUseThread); |
- return v8::Undefined(); |
- } |
- |
- v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 2) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.remove requires 2 parameters")); |
- if (!converted[1]->IsFunction()) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "Second argument to _fileSystem.remove must be a function")); |
- const auto removeTask = std::make_shared<RemoveTask>(jsEngine, converted[1], |
- converted[0]->AsString()); |
- jsEngine->Schedule(AdblockPlus::MakeHeapFunction(removeTask), AdblockPlus::ImmediateSingleUseThread); |
- return v8::Undefined(); |
- } |
- |
- v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 2) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.stat requires 2 parameters")); |
- if (!converted[1]->IsFunction()) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "Second argument to _fileSystem.stat must be a function")); |
- const auto statTask = std::make_shared<StatTask>(jsEngine, converted[1], |
- converted[0]->AsString()); |
- jsEngine->Schedule(AdblockPlus::MakeHeapFunction(statTask), AdblockPlus::ImmediateSingleUseThread); |
- return v8::Undefined(); |
- } |
- |
- v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) |
- { |
- AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arguments); |
- AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |
- |
- v8::Isolate* isolate = arguments.GetIsolate(); |
- if (converted.size() != 1) |
- return v8::ThrowException(Utils::ToV8String(isolate, |
- "_fileSystem.resolve requires 1 parameter")); |
- |
- std::string resolved = jsEngine->GetFileSystem()->Resolve(converted[0]->AsString()); |
- |
- return Utils::ToV8String(isolate, resolved); |
- } |
- |
} |
- |
-JsValuePtr FileSystemJsObject::Setup(JsEnginePtr jsEngine, JsValuePtr obj) |
+v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) |
{ |
- obj->SetProperty("read", jsEngine->NewCallback(::ReadCallback)); |
- obj->SetProperty("write", jsEngine->NewCallback(::WriteCallback)); |
- obj->SetProperty("move", jsEngine->NewCallback(::MoveCallback)); |
- obj->SetProperty("remove", jsEngine->NewCallback(::RemoveCallback)); |
- obj->SetProperty("stat", jsEngine->NewCallback(::StatCallback)); |
- obj->SetProperty("resolve", jsEngine->NewCallback(::ResolveCallback)); |
- return obj; |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::shared_ptr<ReadTask> readTask; |
+ try |
+ { |
+ if (arguments.Length() != 2) |
+ { |
+ throw std::runtime_error("_fileSystem.read requires 2 parameters"); |
+ } |
+ bool argumentIsString; |
+ std::string firstArgument; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.read must be a string"); |
+ } |
+ if (!arguments[1]->IsFunction()) |
+ { |
+ throw std::runtime_error("Second argument to _fileSystem.read must be a function"); |
+ } |
+ readTask = std::make_shared<ReadTask>(engine, firstArgument, |
+ V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::Cast(arguments[1]))); |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ // Run the task |
+ engine->Schedule(AdblockPlus::MakeHeapFunction(readTask), AdblockPlus::ImmediateSingleUseThread); |
+ return v8::Undefined(); |
} |
+ |
+v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) |
+{ |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::shared_ptr<WriteTask> writeTask; |
+ try |
+ { |
+ v8::Isolate* isolate = arguments.GetIsolate(); |
+ |
+ if (arguments.Length() != 3) |
+ { |
+ throw std::exception("_fileSystem.write requires 3 parameters"); |
+ } |
+ bool argumentIsString; |
+ std::string firstArgument; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.write must be a string"); |
+ } |
+ std::string secondArgument; |
+ std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("Second argument to _fileSystem.write must be a string"); |
+ } |
+ if (!arguments[2]->IsFunction()) |
+ { |
+ throw std::runtime_error("Third argument to _fileSystem.write must be a function"); |
+ } |
+ writeTask = std::make_shared<WriteTask>(engine, firstArgument, secondArgument, |
+ V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::Cast(arguments[2]))); |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ engine->Schedule(AdblockPlus::MakeHeapFunction(writeTask), AdblockPlus::ImmediateSingleUseThread); |
+ return v8::Undefined(); |
+} |
+ |
+v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) |
+{ |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::shared_ptr<MoveTask> moveTask; |
+ std::string firstArgument, secondArgument; |
+ try |
+ { |
+ if (arguments.Length() != 3) |
+ { |
+ throw std::runtime_error("_fileSystem.move requires 3 parameters"); |
+ } |
+ bool argumentIsString; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.write must be a string"); |
+ } |
+ std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("Second argument to _fileSystem.write must be a string"); |
+ } |
+ if (!arguments[2]->IsFunction()) |
+ { |
+ throw std::runtime_error("Third argument to _fileSystem.move must be a function"); |
+ } |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ // Run the task |
+ moveTask = std::make_shared<MoveTask>(engine, firstArgument, secondArgument, |
+ V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::Cast(arguments[2]))); |
+ engine->Schedule(AdblockPlus::MakeHeapFunction(moveTask), AdblockPlus::ImmediateSingleUseThread); |
+ return v8::Undefined(); |
+} |
+ |
+v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) |
+{ |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::shared_ptr<RemoveTask> removeTask; |
+ std::string firstArgument; |
+ try |
+ { |
+ if (arguments.Length() != 2) |
+ { |
+ throw std::runtime_error("_fileSystem.remove requires 2 parameters"); |
+ } |
+ bool argumentIsString; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.remove must be a string"); |
+ } |
+ if (!arguments[1]->IsFunction()) |
+ { |
+ throw std::runtime_error("Second argument to _fileSystem.remove must be a function"); |
+ } |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ // Run the task |
+ removeTask = std::make_shared<RemoveTask>(engine, firstArgument, |
+ V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::Cast(arguments[1]))); |
+ engine->Schedule(AdblockPlus::MakeHeapFunction(removeTask), AdblockPlus::ImmediateSingleUseThread); |
+ return v8::Undefined(); |
+} |
+ |
+v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) |
+{ |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::shared_ptr<StatTask> statTask; |
+ std::string firstArgument; |
+ try |
+ { |
+ if (arguments.Length() != 2) |
+ { |
+ throw std::runtime_error("_fileSystem.stat requires 2 parameters"); |
+ } |
+ bool argumentIsString; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.stat must be a string"); |
+ } |
+ if (!arguments[1]->IsFunction()) |
+ { |
+ throw std::runtime_error("Second argument to _fileSystem.stat must be a function"); |
+ } |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ // Run the task |
+ statTask = std::make_shared<StatTask>(engine, firstArgument, |
+ V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::Cast(arguments[1]))); |
+ engine->Schedule(AdblockPlus::MakeHeapFunction(statTask), AdblockPlus::ImmediateSingleUseThread); |
+ return v8::Undefined(); |
+} |
+ |
+v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) |
+{ |
+ auto engine(JsEngineInternal::ExtractEngine(arguments)); |
+ std::string firstArgument; |
+ try |
+ { |
+ if (arguments.Length() != 1) |
+ { |
+ throw std::runtime_error("_fileSystem.resolve requires 1 parameter"); |
+ } |
+ bool argumentIsString; |
+ std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |
+ if (!argumentIsString) |
+ { |
+ throw std::runtime_error("First argument to _fileSystem.write must be a string"); |
+ } |
+ } |
+ catch (const std::exception& e) |
+ { |
+ return v8::ThrowException(engine->ToV8String(e.what())); |
+ } |
+ /* |
+ * Make sure to perform long-lived file system operation with engine unlocked. |
+ */ |
+ std::string resolved = engine->GetFileSystem()->Resolve(firstArgument); |
+ return engine->ToV8String(resolved); |
+} |