Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/FileSystemJsObject.cpp

Issue 29369557: Issue #4692 - Rewrite I/O tasks to avoid engine self-reference
Patch Set: Created Dec. 28, 2016, 5:34 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/FileSystemJsObject.h ('k') | src/GlobalJsObject.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
+}
« no previous file with comments | « src/FileSystemJsObject.h ('k') | src/GlobalJsObject.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld