| Index: src/JsEngine.cpp |
| =================================================================== |
| --- a/src/JsEngine.cpp |
| +++ b/src/JsEngine.cpp |
| @@ -41,37 +41,44 @@ namespace |
| } |
| AdblockPlus::JsError::JsError(const v8::Handle<v8::Value> exception, |
| const v8::Handle<v8::Message> message) |
| : std::runtime_error(ExceptionToString(exception, message)) |
| { |
| } |
| -AdblockPlus::JsEngine::JsEngine(const AppInfo& appInfo) |
| +AdblockPlus::JsEngine::JsEngine() |
| : isolate(v8::Isolate::GetCurrent()) |
| { |
| - const v8::Locker locker(isolate); |
| +} |
| + |
| +AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo) |
|
Felix Dahlke
2013/04/18 18:42:16
I don't think we should have this. "JsEnginePtr x(
Wladimir Palant
2013/04/18 20:24:28
We need to have the object in a shared_ptr before
|
| +{ |
| + JsEnginePtr result(new JsEngine()); |
| + |
| + const v8::Locker locker(result->isolate); |
|
Felix Dahlke
2013/04/18 18:42:16
This is initialisation code, can you move it to th
|
| const v8::HandleScope handleScope; |
| - context = v8::Context::New(); |
| - AdblockPlus::GlobalJsObject::Setup(*this, appInfo, |
| - JsValuePtr(new JsValue(*this, context->Global()))); |
| + result->context = v8::Context::New(); |
| + AdblockPlus::GlobalJsObject::Setup(result, appInfo, |
| + JsValuePtr(new JsValue(result, result->context->Global()))); |
| + return result; |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::Evaluate(const std::string& source, |
| const std::string& filename) |
| { |
| - const Context context(*this); |
| + const Context context(shared_from_this()); |
| const v8::TryCatch tryCatch; |
| const v8::Handle<v8::Script> script = CompileScript(source, filename); |
| CheckTryCatch(tryCatch); |
| v8::Local<v8::Value> result = script->Run(); |
| CheckTryCatch(tryCatch); |
| - return JsValuePtr(new JsValue(*this, result)); |
| + return JsValuePtr(new JsValue(shared_from_this(), result)); |
| } |
| void AdblockPlus::JsEngine::Load(const std::string& scriptPath) |
| { |
| const std::tr1::shared_ptr<std::istream> file = GetFileSystem()->Read(scriptPath); |
| if (!file || !*file) |
| throw std::runtime_error("Unable to load script " + scriptPath); |
| Evaluate(Utils::Slurp(*file)); |
| @@ -79,61 +86,71 @@ void AdblockPlus::JsEngine::Load(const s |
| void AdblockPlus::JsEngine::Gc() |
| { |
| while (!v8::V8::IdleNotification()); |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(const std::string& val) |
| { |
| - const Context context(*this); |
| - return JsValuePtr(new JsValue(*this, v8::String::New(val.c_str(), val.length()))); |
| + const Context context(shared_from_this()); |
| + return JsValuePtr(new JsValue(shared_from_this(), |
| + v8::String::New(val.c_str(), val.length()))); |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(int64_t val) |
| { |
| - const Context context(*this); |
| - return JsValuePtr(new JsValue(*this, v8::Integer::New(val))); |
| + const Context context(shared_from_this()); |
| + return JsValuePtr(new JsValue(shared_from_this(), v8::Integer::New(val))); |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(bool val) |
| { |
| - const Context context(*this); |
| - return JsValuePtr(new JsValue(*this, v8::Boolean::New(val))); |
| + const Context context(shared_from_this()); |
| + return JsValuePtr(new JsValue(shared_from_this(), v8::Boolean::New(val))); |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewObject() |
| { |
| - const Context context(*this); |
| - return JsValuePtr(new JsValue(*this, v8::Object::New())); |
| + const Context context(shared_from_this()); |
| + return JsValuePtr(new JsValue(shared_from_this(), v8::Object::New())); |
| } |
| AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewCallback( |
| v8::InvocationCallback callback) |
| { |
| - const Context context(*this); |
| + const Context context(shared_from_this()); |
| + // Note: we are leaking this weak pointer, no obvious way to destroy it when |
| + // it's no longer used |
| + std::tr1::weak_ptr<JsEngine>* data = |
| + new std::tr1::weak_ptr<JsEngine>(shared_from_this()); |
| v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback, |
| - v8::External::New(this)); |
| - return JsValuePtr(new JsValue(*this, templ->GetFunction())); |
| + v8::External::New(data)); |
| + return JsValuePtr(new JsValue(shared_from_this(), templ->GetFunction())); |
| } |
| -AdblockPlus::JsEngine& AdblockPlus::JsEngine::FromArguments(const v8::Arguments& arguments) |
| +AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Arguments& arguments) |
| { |
| const v8::Local<const v8::External> external = |
| v8::Local<const v8::External>::Cast(arguments.Data()); |
| - return *static_cast<JsEngine* const>(external->Value()); |
| + std::tr1::weak_ptr<JsEngine>* data = |
| + static_cast<std::tr1::weak_ptr<JsEngine>*>(external->Value()); |
| + JsEnginePtr result = data->lock(); |
| + if (!result) |
| + throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?"); |
| + return result; |
| } |
| AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Arguments& arguments) |
| { |
| - const Context context(*this); |
| + const Context context(shared_from_this()); |
| JsValueList list; |
| for (int i = 0; i < arguments.Length(); i++) |
| - list.push_back(JsValuePtr(new JsValue(*this, arguments[i]))); |
| + list.push_back(JsValuePtr(new JsValue(shared_from_this(), arguments[i]))); |
| return list; |
| } |
| AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem() |
| { |
| if (!fileSystem) |
| fileSystem.reset(new DefaultFileSystem()); |
| return fileSystem; |
| @@ -172,13 +189,13 @@ AdblockPlus::ErrorCallbackPtr AdblockPlu |
| void AdblockPlus::JsEngine::SetErrorCallback(AdblockPlus::ErrorCallbackPtr val) |
| { |
| if (!val) |
| throw std::runtime_error("ErrorCallback cannot be null"); |
| errorCallback = val; |
| } |
| -AdblockPlus::JsEngine::Context::Context(const JsEngine& jsEngine) |
| - : locker(jsEngine.isolate), handleScope(), |
| - contextScope(jsEngine.context) |
| +AdblockPlus::JsEngine::Context::Context(const JsEnginePtr jsEngine) |
| + : locker(jsEngine->isolate), handleScope(), |
| + contextScope(jsEngine->context) |
| { |
| } |