| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 private: | 101 private: |
| 102 ScopedV8Isolate(const ScopedV8Isolate&); | 102 ScopedV8Isolate(const ScopedV8Isolate&); |
| 103 ScopedV8Isolate& operator=(const ScopedV8Isolate&); | 103 ScopedV8Isolate& operator=(const ScopedV8Isolate&); |
| 104 | 104 |
| 105 v8::Isolate* isolate; | 105 v8::Isolate* isolate; |
| 106 }; | 106 }; |
| 107 } | 107 } |
| 108 | 108 |
| 109 using namespace AdblockPlus; | 109 using namespace AdblockPlus; |
| 110 | 110 |
| 111 JsEngine::JsWeakValuesList::~JsWeakValuesList() | 111 template <> JsWeakValuesList<v8::Global<v8::Value>>::~JsWeakValuesList() |
| 112 { | 112 { |
| 113 } | 113 } |
| 114 | 114 |
| 115 void JsEngine::NotifyLowMemory() | 115 |
| 116 template <> void AdblockPlus::JSENGINEV8::NotifyLowMemory() |
| 116 { | 117 { |
| 117 const JsContext context(*this); | 118 const JsContext context(*this); |
| 118 GetIsolate()->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical); | 119 GetIsolate()->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical); |
| 119 } | 120 } |
| 120 | 121 |
| 121 void JsEngine::ScheduleTimer(const v8::FunctionCallbackInfo<v8::Value>& argument
s) | 122 template <> void AdblockPlus::JSENGINEV8::ScheduleTimer(const v8::FunctionCallba
ckInfo<v8::Value>& arguments) |
| 122 { | 123 { |
| 123 auto jsEngine = FromArguments(arguments); | 124 auto jsEngine = FromArguments(arguments); |
| 124 if (arguments.Length() < 2) | 125 if (arguments.Length() < 2) |
| 125 throw std::runtime_error("setTimeout requires at least 2 parameters"); | 126 throw std::runtime_error("setTimeout requires at least 2 parameters"); |
| 126 | 127 |
| 127 if (!arguments[0]->IsFunction()) | 128 if (!arguments[0]->IsFunction()) |
| 128 throw std::runtime_error("First argument to setTimeout must be a function"); | 129 throw std::runtime_error("First argument to setTimeout must be a function"); |
| 129 | 130 |
| 130 auto jsValueArguments = jsEngine->ConvertArguments(arguments); | 131 auto jsValueArguments = jsEngine->ConvertArguments(arguments); |
| 131 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); | 132 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); |
| 132 | 133 |
| 133 std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 134 std::weak_ptr<JsEngine> weakJsEngine = jsEngine; |
| 134 jsEngine->platform.WithTimer( | 135 jsEngine->platform.WithTimer( |
| 135 [arguments, weakJsEngine, timerParamsID](ITimer& timer) | 136 [arguments, weakJsEngine, timerParamsID](ITimer& timer) |
| 136 { | 137 { |
| 137 timer.SetTimer( | 138 timer.SetTimer( |
| 138 std::chrono::milliseconds( | 139 std::chrono::milliseconds( |
| 139 arguments[1]->IntegerValue()), [weakJsEngine, timerParamsID] | 140 arguments[1]->IntegerValue()), [weakJsEngine, timerParamsID] |
| 140 { | 141 { |
| 141 if (auto jsEngine = weakJsEngine.lock()) | 142 if (auto jsEngine = weakJsEngine.lock()) |
| 142 jsEngine->CallTimerTask(timerParamsID); | 143 jsEngine->CallTimerTask(timerParamsID); |
| 143 }); | 144 }); |
| 144 }); | 145 }); |
| 145 } | 146 } |
| 146 | 147 |
| 147 void JsEngine::CallTimerTask(const JsWeakValuesID& timerParamsID) | 148 template <> void AdblockPlus::JSENGINEV8::CallTimerTask(const JsWeakValuesID& ti
merParamsID) |
| 148 { | 149 { |
| 149 auto timerParams = TakeJsValues(timerParamsID); | 150 auto timerParams = TakeJsValues(timerParamsID); |
| 150 JsValue callback = std::move(timerParams[0]); | 151 JsValue callback = std::move(timerParams[0]); |
| 151 | 152 |
| 152 timerParams.erase(timerParams.begin()); // remove callback placeholder | 153 timerParams.erase(timerParams.begin()); // remove callback placeholder |
| 153 timerParams.erase(timerParams.begin()); // remove timeout param | 154 timerParams.erase(timerParams.begin()); // remove timeout param |
| 154 callback.Call(timerParams); | 155 callback.Call(timerParams); |
| 155 } | 156 } |
| 156 | 157 |
| 157 AdblockPlus::JsEngine::JsEngine(Platform& platform, std::unique_ptr<IV8IsolatePr
ovider> isolate) | 158 template <> AdblockPlus::JSENGINEV8::JsEngineTemplate(Platform& platform, std::u
nique_ptr<IV8IsolateProvider> isolate) |
| 158 : platform(platform) | 159 : platform(platform) |
| 159 , isolate(std::move(isolate)) | 160 , isolate(std::move(isolate)) |
| 160 { | 161 { |
| 161 } | 162 } |
| 162 | 163 |
| 163 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo, | 164 |
| 165 template <> AdblockPlus::JsEnginePtr AdblockPlus::JSENGINEV8::New(const AppInfo&
appInfo, |
| 164 Platform& platform, std::unique_ptr<IV8IsolateProvider> isolate) | 166 Platform& platform, std::unique_ptr<IV8IsolateProvider> isolate) |
| 165 { | 167 { |
| 166 if (!isolate) | 168 if (!isolate) |
| 167 { | 169 { |
| 168 isolate.reset(new ScopedV8Isolate()); | 170 isolate.reset(new ScopedV8Isolate()); |
| 169 } | 171 } |
| 170 JsEnginePtr result(new JsEngine(platform, std::move(isolate))); | 172 JsEnginePtr result(new JsEngine(platform, std::move(isolate))); |
| 171 | 173 |
| 172 const v8::Locker locker(result->GetIsolate()); | 174 const v8::Locker locker(result->GetIsolate()); |
| 173 const v8::Isolate::Scope isolateScope(result->GetIsolate()); | 175 const v8::Isolate::Scope isolateScope(result->GetIsolate()); |
| 174 const v8::HandleScope handleScope(result->GetIsolate()); | 176 const v8::HandleScope handleScope(result->GetIsolate()); |
| 175 | 177 |
| 176 result->context.reset(new v8::Global<v8::Context>(result->GetIsolate(), | 178 result->context.reset(new v8::Global<v8::Context>(result->GetIsolate(), |
| 177 v8::Context::New(result->GetIsolate()))); | 179 v8::Context::New(result->GetIsolate()))); |
| 178 auto global = result->GetGlobalObject(); | 180 auto global = result->GetGlobalObject(); |
| 179 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); | 181 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); |
| 180 return result; | 182 return result; |
| 181 } | 183 } |
| 182 | 184 |
| 183 AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject() | 185 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::GetGlobalObject() |
| 184 { | 186 { |
| 185 JsContext context(*this); | 187 JsContext context(*this); |
| 186 return JsValue(shared_from_this(), context.GetV8Context()->Global()); | 188 return JsValue(shared_from_this(), context.GetJSEngineContext()->Global()); |
| 187 } | 189 } |
| 188 | 190 |
| 189 AdblockPlus::JsValue AdblockPlus::JsEngine::Evaluate(const std::string& source, | 191 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::Evaluate(const std::st
ring& source, |
| 190 const std::string& filename) | 192 const std::string& filename) |
| 191 { | 193 { |
| 192 const JsContext context(*this); | 194 const JsContext context(*this); |
| 193 const v8::TryCatch tryCatch; | 195 const v8::TryCatch tryCatch; |
| 194 const v8::Handle<v8::Script> script = CompileScript(GetIsolate(), source, | 196 const v8::Handle<v8::Script> script = CompileScript(GetIsolate(), source, |
| 195 filename); | 197 filename); |
| 196 CheckTryCatch(tryCatch); | 198 CheckTryCatch(tryCatch); |
| 197 v8::Local<v8::Value> result = script->Run(); | 199 v8::Local<v8::Value> result = script->Run(); |
| 198 CheckTryCatch(tryCatch); | 200 CheckTryCatch(tryCatch); |
| 199 return JsValue(shared_from_this(), result); | 201 return JsValue(shared_from_this(), result); |
| 200 } | 202 } |
| 201 | 203 |
| 202 void AdblockPlus::JsEngine::SetEventCallback(const std::string& eventName, | 204 template <> void AdblockPlus::JSENGINEV8::SetEventCallback(const std::string& ev
entName, |
| 203 const AdblockPlus::JsEngine::EventCallback& callback) | 205 const AdblockPlus::JSENGINEV8::EventCallback& callback) |
| 204 { | 206 { |
| 205 if (!callback) | 207 if (!callback) |
| 206 { | 208 { |
| 207 RemoveEventCallback(eventName); | 209 RemoveEventCallback(eventName); |
| 208 return; | 210 return; |
| 209 } | 211 } |
| 210 std::lock_guard<std::mutex> lock(eventCallbacksMutex); | 212 std::lock_guard<std::mutex> lock(eventCallbacksMutex); |
| 211 eventCallbacks[eventName] = callback; | 213 eventCallbacks[eventName] = callback; |
| 212 } | 214 } |
| 213 | 215 |
| 214 void AdblockPlus::JsEngine::RemoveEventCallback(const std::string& eventName) | 216 template <> void AdblockPlus::JSENGINEV8::RemoveEventCallback(const std::string&
eventName) |
| 215 { | 217 { |
| 216 std::lock_guard<std::mutex> lock(eventCallbacksMutex); | 218 std::lock_guard<std::mutex> lock(eventCallbacksMutex); |
| 217 eventCallbacks.erase(eventName); | 219 eventCallbacks.erase(eventName); |
| 218 } | 220 } |
| 219 | 221 |
| 220 void AdblockPlus::JsEngine::TriggerEvent(const std::string& eventName, AdblockPl
us::JsValueList&& params) | 222 template <> void AdblockPlus::JSENGINEV8::TriggerEvent(const std::string& eventN
ame, AdblockPlus::JsValueList&& params) |
| 221 { | 223 { |
| 222 EventCallback callback; | 224 EventCallback callback; |
| 223 { | 225 { |
| 224 std::lock_guard<std::mutex> lock(eventCallbacksMutex); | 226 std::lock_guard<std::mutex> lock(eventCallbacksMutex); |
| 225 auto it = eventCallbacks.find(eventName); | 227 auto it = eventCallbacks.find(eventName); |
| 226 if (it == eventCallbacks.end()) | 228 if (it == eventCallbacks.end()) |
| 227 return; | 229 return; |
| 228 callback = it->second; | 230 callback = it->second; |
| 229 } | 231 } |
| 230 callback(move(params)); | 232 callback(move(params)); |
| 231 } | 233 } |
| 232 | 234 |
| 233 void AdblockPlus::JsEngine::Gc() | 235 template <> void AdblockPlus::JSENGINEV8::Gc() |
| 234 { | 236 { |
| 235 while (!GetIsolate()->IdleNotification(1000)); | 237 while (!GetIsolate()->IdleNotification(1000)); |
| 236 } | 238 } |
| 237 | 239 |
| 238 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(const std::string& val) | 240 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::NewValue(const std::st
ring& val) |
| 239 { | 241 { |
| 240 const JsContext context(*this); | 242 const JsContext context(*this); |
| 241 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); | 243 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); |
| 242 } | 244 } |
| 243 | 245 |
| 244 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(int64_t val) | 246 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::NewValue(int64_t val) |
| 245 { | 247 { |
| 246 const JsContext context(*this); | 248 const JsContext context(*this); |
| 247 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); | 249 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); |
| 248 } | 250 } |
| 249 | 251 |
| 250 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(bool val) | 252 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::NewValue(bool val) |
| 251 { | 253 { |
| 252 const JsContext context(*this); | 254 const JsContext context(*this); |
| 253 return JsValue(shared_from_this(), v8::Boolean::New(GetIsolate(), val)); | 255 return JsValue(shared_from_this(), v8::Boolean::New(GetIsolate(), val)); |
| 254 } | 256 } |
| 255 | 257 |
| 256 AdblockPlus::JsValue AdblockPlus::JsEngine::NewObject() | 258 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::NewObject() |
| 257 { | 259 { |
| 258 const JsContext context(*this); | 260 const JsContext context(*this); |
| 259 return JsValue(shared_from_this(), v8::Object::New(GetIsolate())); | 261 return JsValue(shared_from_this(), v8::Object::New(GetIsolate())); |
| 260 } | 262 } |
| 261 | 263 |
| 262 AdblockPlus::JsValue AdblockPlus::JsEngine::NewCallback( | 264 template <> AdblockPlus::JsValue AdblockPlus::JSENGINEV8::NewCallback( |
| 263 const v8::FunctionCallback& callback) | 265 const v8::FunctionCallback& callback) |
| 264 { | 266 { |
| 265 const JsContext context(*this); | 267 const JsContext context(*this); |
| 266 | 268 |
| 267 // Note: we are leaking this weak pointer, no obvious way to destroy it when | 269 // Note: we are leaking this weak pointer, no obvious way to destroy it when |
| 268 // it's no longer used | 270 // it's no longer used |
| 269 std::weak_ptr<JsEngine>* data = | 271 std::weak_ptr<JsEngine>* data = |
| 270 new std::weak_ptr<JsEngine>(shared_from_this()); | 272 new std::weak_ptr<JsEngine>(shared_from_this()); |
| 271 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(GetIsolate()
, callback, | 273 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(GetIsolate()
, callback, |
| 272 v8::External::New(GetIsolate(), data)); | 274 v8::External::New(GetIsolate(), data)); |
| 273 return JsValue(shared_from_this(), templ->GetFunction()); | 275 return JsValue(shared_from_this(), templ->GetFunction()); |
| 274 } | 276 } |
| 275 | 277 |
| 276 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Function
CallbackInfo<v8::Value>& arguments) | 278 template <> AdblockPlus::JsEnginePtr AdblockPlus::JSENGINEV8::FromArguments(cons
t v8::FunctionCallbackInfo<v8::Value>& arguments) |
| 277 { | 279 { |
| 278 const v8::Local<const v8::External> external = | 280 const v8::Local<const v8::External> external = |
| 279 v8::Local<const v8::External>::Cast(arguments.Data()); | 281 v8::Local<const v8::External>::Cast(arguments.Data()); |
| 280 std::weak_ptr<JsEngine>* data = | 282 std::weak_ptr<JsEngine>* data = |
| 281 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); | 283 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); |
| 282 JsEnginePtr result = data->lock(); | 284 JsEnginePtr result = data->lock(); |
| 283 if (!result) | 285 if (!result) |
| 284 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; | 286 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; |
| 285 return result; | 287 return result; |
| 286 } | 288 } |
| 287 | 289 |
| 288 JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) | 290 template <> AdblockPlus::JsWeakValuesID AdblockPlus::JSENGINEV8::StoreJsValues(c
onst JsValueList& values) |
| 289 { | 291 { |
| 290 JsWeakValuesLists::iterator it; | 292 JsWeakValuesLists::iterator it; |
| 291 { | 293 { |
| 292 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 294 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
| 293 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); | 295 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); |
| 294 } | 296 } |
| 295 { | 297 { |
| 296 JsContext context(*this); | 298 JsContext context(*this); |
| 297 for (const auto& value : values) | 299 for (const auto& value : values) |
| 298 { | 300 { |
| 299 it->values.emplace_back(GetIsolate(), value.UnwrapValue()); | 301 it->values.emplace_back(GetIsolate(), value.UnwrapValue()); |
| 300 } | 302 } |
| 301 } | 303 } |
| 302 JsWeakValuesID retValue; | 304 JsWeakValuesID retValue; |
| 303 retValue.iterator = it; | 305 retValue.iterator = it; |
| 304 return retValue; | 306 return retValue; |
| 305 } | 307 } |
| 306 | 308 |
| 307 JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) | 309 template <> JsValueList JSENGINEV8::TakeJsValues(const JsWeakValuesID& id) |
| 308 { | 310 { |
| 309 JsValueList retValue; | 311 JsValueList retValue; |
| 310 { | 312 { |
| 311 JsContext context(*this); | 313 JsContext context(*this); |
| 312 for (const auto& v8Value : id.iterator->values) | 314 for (const auto& v8Value : id.iterator->values) |
| 313 { | 315 { |
| 314 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), v8Value))); | 316 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), v8Value))); |
| 315 } | 317 } |
| 316 } | 318 } |
| 317 { | 319 { |
| 318 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 320 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
| 319 jsWeakValuesLists.erase(id.iterator); | 321 jsWeakValuesLists.erase(id.iterator); |
| 320 } | 322 } |
| 321 return retValue; | 323 return retValue; |
| 322 } | 324 } |
| 323 | 325 |
| 324 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Funct
ionCallbackInfo<v8::Value>& arguments) | 326 template <> AdblockPlus::JsValueList AdblockPlus::JSENGINEV8::ConvertArguments(c
onst v8::FunctionCallbackInfo<v8::Value>& arguments) |
| 325 { | 327 { |
| 326 const JsContext context(*this); | 328 const JsContext context(*this); |
| 327 JsValueList list; | 329 JsValueList list; |
| 328 for (int i = 0; i < arguments.Length(); i++) | 330 for (int i = 0; i < arguments.Length(); i++) |
| 329 list.push_back(JsValue(shared_from_this(), arguments[i])); | 331 list.push_back(JsValue(shared_from_this(), arguments[i])); |
| 330 return list; | 332 return list; |
| 331 } | 333 } |
| 332 | 334 |
| 333 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name, | 335 void AdblockPlus::JSENGINEV8::SetGlobalProperty(const std::string& name, |
| 334 const AdblockPlus::JsValue& value) | 336 const AdblockPlus::JsValue& value) |
| 335 { | 337 { |
| 336 auto global = GetGlobalObject(); | 338 auto global = GetGlobalObject(); |
| 337 global.SetProperty(name, value); | 339 global.SetProperty(name, value); |
| 338 } | 340 } |
| OLD | NEW |