Index: src/JsValue.cpp |
diff --git a/src/JsValue.cpp b/src/JsValue.cpp |
index d2dda5a5df3981132a8b6956f228d12f0cd2916a..faad64058e31a0747f46a7e55094ec1c80c22716 100644 |
--- a/src/JsValue.cpp |
+++ b/src/JsValue.cpp |
@@ -22,105 +22,112 @@ |
#include "JsError.h" |
#include "Utils.h" |
-AdblockPlus::JsValue::JsValue(AdblockPlus::JsEnginePtr jsEngine, |
- v8::Handle<v8::Value> value) |
- : jsEngine(jsEngine), |
- value(new v8::Persistent<v8::Value>(jsEngine->GetIsolate(), value)) |
+AdblockPlus::JsValue::JsValue(const std::weak_ptr<AdblockPlus::JsEngine>& jsEngine, |
+ v8::Handle<v8::Value> value) |
+ : jsEngine(jsEngine) |
+ , value(new v8::Persistent<v8::Value>(Utils::lockJsEngine(jsEngine)->GetIsolate(), value)) |
Eric
2016/11/28 14:21:13
This use of 'lockJsEngine' has a race condition. T
sergei
2016/11/29 10:45:18
lockJsEngine returns an object not a reference or
|
{ |
} |
AdblockPlus::JsValue::JsValue(AdblockPlus::JsValue&& src) |
- : jsEngine(src.jsEngine), |
+ : jsEngine(move(src.jsEngine)), |
value(std::move(src.value)) |
Eric
2016/11/28 14:21:13
For consistency, this should either be (1) `std::m
sergei
2016/11/29 10:45:19
I have added std:: rather for aesthetic view than
|
{ |
} |
AdblockPlus::JsValue::~JsValue() |
{ |
- if (value) |
+ try |
+ { |
+ JsContext context(jsEngine); |
+ if (value) |
+ { |
+ value->Dispose(); |
+ value.reset(); |
+ } |
+ } |
+ catch (const JsEngine::JsEngineNotAvailableException&) |
{ |
- value->Dispose(); |
- value.reset(); |
} |
} |
Eric
2016/11/28 14:21:14
It's excessive to instantiate a `JsContext` object
sergei
2016/11/29 10:45:18
JsContext is not only to ensure that JsEngine is s
|
bool AdblockPlus::JsValue::IsUndefined() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IsUndefined(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IsUndefined(); |
} |
bool AdblockPlus::JsValue::IsNull() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IsNull(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IsNull(); |
} |
bool AdblockPlus::JsValue::IsString() const |
{ |
- const JsContext context(jsEngine); |
- v8::Local<v8::Value> value = UnwrapValue(); |
+ JsContext context(jsEngine); |
+ v8::Local<v8::Value> value = UnwrapValue(context.GetJsEngine()); |
return value->IsString() || value->IsStringObject(); |
} |
bool AdblockPlus::JsValue::IsNumber() const |
{ |
- const JsContext context(jsEngine); |
- v8::Local<v8::Value> value = UnwrapValue(); |
+ JsContext context(jsEngine); |
+ v8::Local<v8::Value> value = UnwrapValue(context.GetJsEngine()); |
return value->IsNumber() || value->IsNumberObject(); |
} |
bool AdblockPlus::JsValue::IsBool() const |
{ |
- const JsContext context(jsEngine); |
- v8::Local<v8::Value> value = UnwrapValue(); |
+ JsContext context(jsEngine); |
+ v8::Local<v8::Value> value = UnwrapValue(context.GetJsEngine()); |
return value->IsBoolean() || value->IsBooleanObject(); |
} |
bool AdblockPlus::JsValue::IsObject() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IsObject(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IsObject(); |
} |
bool AdblockPlus::JsValue::IsArray() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IsArray(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IsArray(); |
} |
bool AdblockPlus::JsValue::IsFunction() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IsFunction(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IsFunction(); |
} |
std::string AdblockPlus::JsValue::AsString() const |
{ |
- const JsContext context(jsEngine); |
- return Utils::FromV8String(UnwrapValue()); |
+ JsContext context(jsEngine); |
+ return Utils::FromV8String(UnwrapValue(context.GetJsEngine())); |
} |
int64_t AdblockPlus::JsValue::AsInt() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->IntegerValue(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->IntegerValue(); |
} |
bool AdblockPlus::JsValue::AsBool() const |
{ |
- const JsContext context(jsEngine); |
- return UnwrapValue()->BooleanValue(); |
+ JsContext context(jsEngine); |
+ return UnwrapValue(context.GetJsEngine())->BooleanValue(); |
} |
AdblockPlus::JsValueList AdblockPlus::JsValue::AsList() const |
{ |
+ JsContext context(jsEngine); |
if (!IsArray()) |
throw std::runtime_error("Cannot convert a non-array to list"); |
- const JsContext context(jsEngine); |
JsValueList result; |
- v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(UnwrapValue()); |
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(UnwrapValue(context.GetJsEngine())); |
uint32_t length = array->Length(); |
for (uint32_t i = 0; i < length; i++) |
{ |
@@ -132,11 +139,11 @@ AdblockPlus::JsValueList AdblockPlus::JsValue::AsList() const |
std::vector<std::string> AdblockPlus::JsValue::GetOwnPropertyNames() const |
{ |
+ JsContext context(jsEngine); |
if (!IsObject()) |
throw new std::runtime_error("Attempting to get propert list for a non-object"); |
- const JsContext context(jsEngine); |
- v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(UnwrapValue()); |
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(UnwrapValue(context.GetJsEngine())); |
JsValueList properties = JsValuePtr(new JsValue(jsEngine, object->GetOwnPropertyNames()))->AsList(); |
std::vector<std::string> result; |
for (JsValueList::iterator it = properties.begin(); it != properties.end(); ++it) |
@@ -147,86 +154,87 @@ std::vector<std::string> AdblockPlus::JsValue::GetOwnPropertyNames() const |
AdblockPlus::JsValuePtr AdblockPlus::JsValue::GetProperty(const std::string& name) const |
{ |
+ JsContext context(jsEngine); |
if (!IsObject()) |
throw new std::runtime_error("Attempting to get property of a non-object"); |
- const JsContext context(jsEngine); |
- v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), name); |
- v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
+ v8::Local<v8::String> property = Utils::ToV8String(context.GetJsEngine().GetIsolate(), name); |
+ v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue(context.GetJsEngine())); |
return JsValuePtr(new JsValue(jsEngine, obj->Get(property))); |
} |
void AdblockPlus::JsValue::SetProperty(const std::string& name, v8::Handle<v8::Value> val) |
{ |
+ JsContext context(jsEngine); |
if (!IsObject()) |
throw new std::runtime_error("Attempting to set property on a non-object"); |
- v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), name); |
- v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
+ v8::Local<v8::String> property = Utils::ToV8String(context.GetJsEngine().GetIsolate(), name); |
+ v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue(context.GetJsEngine())); |
obj->Set(property, val); |
} |
-v8::Local<v8::Value> AdblockPlus::JsValue::UnwrapValue() const |
+v8::Local<v8::Value> AdblockPlus::JsValue::UnwrapValue(JsEngine& jsEngine) const |
{ |
- return v8::Local<v8::Value>::New(jsEngine->GetIsolate(), *value); |
+ return v8::Local<v8::Value>::New(jsEngine.GetIsolate(), *value); |
} |
void AdblockPlus::JsValue::SetProperty(const std::string& name, const std::string& val) |
{ |
- const JsContext context(jsEngine); |
- SetProperty(name, Utils::ToV8String(jsEngine->GetIsolate(), val)); |
+ JsContext context(jsEngine); |
+ SetProperty(name, Utils::ToV8String(context.GetJsEngine().GetIsolate(), val)); |
} |
void AdblockPlus::JsValue::SetProperty(const std::string& name, int64_t val) |
{ |
- const JsContext context(jsEngine); |
- SetProperty(name, v8::Number::New(jsEngine->GetIsolate(), val)); |
+ JsContext context(jsEngine); |
+ SetProperty(name, v8::Number::New(context.GetJsEngine().GetIsolate(), val)); |
} |
void AdblockPlus::JsValue::SetProperty(const std::string& name, const JsValuePtr& val) |
{ |
- const JsContext context(jsEngine); |
- SetProperty(name, val->UnwrapValue()); |
+ JsContext context(jsEngine); |
+ SetProperty(name, val->UnwrapValue(context.GetJsEngine())); |
} |
void AdblockPlus::JsValue::SetProperty(const std::string& name, bool val) |
{ |
- const JsContext context(jsEngine); |
+ JsContext context(jsEngine); |
SetProperty(name, v8::Boolean::New(val)); |
} |
std::string AdblockPlus::JsValue::GetClass() const |
{ |
+ JsContext context(jsEngine); |
if (!IsObject()) |
throw new std::runtime_error("Cannot get constructor of a non-object"); |
- const JsContext context(jsEngine); |
- v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
+ v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue(context.GetJsEngine())); |
return Utils::FromV8String(obj->GetConstructorName()); |
} |
AdblockPlus::JsValuePtr AdblockPlus::JsValue::Call(const JsValueList& params, JsValuePtr thisPtr) const |
{ |
+ JsContext context(jsEngine); |
if (!IsFunction()) |
throw new std::runtime_error("Attempting to call a non-function"); |
- const JsContext context(jsEngine); |
if (!thisPtr) |
{ |
v8::Local<v8::Context> localContext = v8::Local<v8::Context>::New( |
- jsEngine->GetIsolate(), *jsEngine->context); |
+ context.GetJsEngine().GetIsolate(), *context.GetJsEngine().context); |
thisPtr = JsValuePtr(new JsValue(jsEngine, localContext->Global())); |
} |
if (!thisPtr->IsObject()) |
throw new std::runtime_error("`this` pointer has to be an object"); |
- v8::Local<v8::Object> thisObj = v8::Local<v8::Object>::Cast(thisPtr->UnwrapValue()); |
+ v8::Local<v8::Object> thisObj = v8::Local<v8::Object>::Cast(thisPtr->UnwrapValue(context.GetJsEngine())); |
std::vector<v8::Handle<v8::Value>> argv; |
for (JsValueList::const_iterator it = params.begin(); it != params.end(); ++it) |
- argv.push_back((*it)->UnwrapValue()); |
+ argv.push_back((*it)->UnwrapValue(context.GetJsEngine())); |
const v8::TryCatch tryCatch; |
- v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(UnwrapValue()); |
+ v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(UnwrapValue(context.GetJsEngine())); |
v8::Local<v8::Value> result = func->Call(thisObj, argv.size(), |
argv.size() ? &argv.front() : 0); |
@@ -238,8 +246,8 @@ AdblockPlus::JsValuePtr AdblockPlus::JsValue::Call(const JsValueList& params, Js |
AdblockPlus::JsValuePtr AdblockPlus::JsValue::Call(const JsValue& arg) const |
{ |
- const JsContext context(jsEngine); |
+ JsContext context(jsEngine); |
JsValueList params; |
- params.push_back(JsValuePtr(new JsValue(arg.jsEngine, arg.UnwrapValue()))); |
+ params.push_back(JsValuePtr(new JsValue(arg.jsEngine, arg.UnwrapValue(context.GetJsEngine())))); |
return Call(params); |
} |