Index: src/JsEngine.cpp |
diff --git a/src/JsEngine.cpp b/src/JsEngine.cpp |
index 71be92f3735f5036adba4dbb03a64378ad98430f..88c7d375a12bd60eaf7ff1589a9d2e963270a5f7 100644 |
--- a/src/JsEngine.cpp |
+++ b/src/JsEngine.cpp |
@@ -84,10 +84,10 @@ AdblockPlus::ScopedV8Isolate::~ScopedV8Isolate() |
isolate = nullptr; |
} |
-JsEngine::TimerTask::~TimerTask() |
+JsEngine::JsWeakValuesList::~JsWeakValuesList() |
{ |
- for (auto& arg : arguments) |
- arg->Dispose(); |
+ for (auto& value : values) |
+ value->Dispose(); |
} |
void JsEngine::ScheduleTimer(const v8::Arguments& arguments) |
@@ -99,29 +99,25 @@ void JsEngine::ScheduleTimer(const v8::Arguments& arguments) |
if (!arguments[0]->IsFunction()) |
throw std::runtime_error("First argument to setTimeout must be a function"); |
- auto timerTaskIterator = jsEngine->timerTasks.emplace(jsEngine->timerTasks.end()); |
- |
- for (int i = 0; i < arguments.Length(); i++) |
- timerTaskIterator->arguments.emplace_back(new v8::Persistent<v8::Value>(jsEngine->GetIsolate(), arguments[i])); |
+ auto jsValueArguments = jsEngine->ConvertArguments(arguments); |
+ auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); |
std::weak_ptr<JsEngine> weakJsEngine = jsEngine; |
- jsEngine->timer->SetTimer(std::chrono::milliseconds(arguments[1]->IntegerValue()), [weakJsEngine, timerTaskIterator] |
+ jsEngine->timer->SetTimer(std::chrono::milliseconds(arguments[1]->IntegerValue()), [weakJsEngine, timerParamsID] |
{ |
if (auto jsEngine = weakJsEngine.lock()) |
- jsEngine->CallTimerTask(timerTaskIterator); |
+ jsEngine->CallTimerTask(timerParamsID); |
}); |
} |
-void JsEngine::CallTimerTask(const TimerTasks::const_iterator& timerTaskIterator) |
+void JsEngine::CallTimerTask(const JsWeakValuesID& timerParamsID) |
{ |
- const JsContext context(*this); |
- JsValue callback(shared_from_this(), v8::Local<v8::Value>::New(GetIsolate(), *timerTaskIterator->arguments[0])); |
- JsValueList callbackArgs; |
- for (int i = 2; i < timerTaskIterator->arguments.size(); i++) |
- callbackArgs.emplace_back(JsValue(shared_from_this(), |
- v8::Local<v8::Value>::New(GetIsolate(), *timerTaskIterator->arguments[i]))); |
- callback.Call(callbackArgs); |
- timerTasks.erase(timerTaskIterator); |
+ auto timerParams = TakeJsValues(timerParamsID); |
+ JsValue callback = std::move(timerParams[0]); |
+ |
+ timerParams.erase(timerParams.begin()); // remove callback placeholder |
+ timerParams.erase(timerParams.begin()); // remove timeout param |
+ callback.Call(timerParams); |
} |
AdblockPlus::JsEngine::JsEngine(const ScopedV8IsolatePtr& isolate, TimerPtr timer) |
@@ -255,6 +251,42 @@ AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Argument |
return result; |
} |
+JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) |
+{ |
+ JsWeakValuesLists::iterator it; |
+ { |
+ std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
+ it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); |
+ } |
+ { |
+ JsContext context(*this); |
+ for (const auto& value : values) |
+ { |
+ it->values.emplace_back(new v8::Persistent<v8::Value>(GetIsolate(), value.UnwrapValue())); |
+ } |
+ } |
+ JsWeakValuesID retValue; |
+ retValue.iterator = it; |
+ return retValue; |
+} |
+ |
+JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) |
+{ |
+ JsValueList retValue; |
+ { |
+ JsContext context(*this); |
+ for (const auto& v8Value : id.iterator->values) |
+ { |
+ retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::New(GetIsolate(), *v8Value))); |
+ } |
+ } |
+ { |
+ std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
+ jsWeakValuesLists.erase(id.iterator); |
+ } |
+ return retValue; |
+} |
+ |
AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Arguments& arguments) |
{ |
const JsContext context(*this); |