LEFT | RIGHT |
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-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 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 |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include <AdblockPlus.h> | 18 #include <AdblockPlus.h> |
19 #include "GlobalJsObject.h" | 19 #include "GlobalJsObject.h" |
20 #include "JsContext.h" | 20 #include "JsContext.h" |
21 #include "JsError.h" | 21 #include "JsError.h" |
22 #include "Utils.h" | 22 #include "Utils.h" |
23 #include "DefaultTimer.h" | 23 #include "DefaultTimer.h" |
| 24 #include <libplatform/libplatform.h> |
24 | 25 |
25 namespace | 26 namespace |
26 { | 27 { |
27 v8::Handle<v8::Script> CompileScript(v8::Isolate* isolate, | 28 v8::Handle<v8::Script> CompileScript(v8::Isolate* isolate, |
28 const std::string& source, const std::string& filename) | 29 const std::string& source, const std::string& filename) |
29 { | 30 { |
30 using AdblockPlus::Utils::ToV8String; | 31 using AdblockPlus::Utils::ToV8String; |
31 const v8::Handle<v8::String> v8Source = ToV8String(isolate, source); | 32 const v8::Handle<v8::String> v8Source = ToV8String(isolate, source); |
32 if (filename.length()) | 33 if (filename.length()) |
33 { | 34 { |
34 const v8::Handle<v8::String> v8Filename = ToV8String(isolate, filename); | 35 const v8::Handle<v8::String> v8Filename = ToV8String(isolate, filename); |
35 return v8::Script::Compile(v8Source, v8Filename); | 36 return v8::Script::Compile(v8Source, v8Filename); |
36 } | 37 } |
37 else | 38 else |
38 return v8::Script::Compile(v8Source); | 39 return v8::Script::Compile(v8Source); |
39 } | 40 } |
40 | 41 |
41 void CheckTryCatch(const v8::TryCatch& tryCatch) | 42 void CheckTryCatch(const v8::TryCatch& tryCatch) |
42 { | 43 { |
43 if (tryCatch.HasCaught()) | 44 if (tryCatch.HasCaught()) |
44 throw AdblockPlus::JsError(tryCatch.Exception(), tryCatch.Message()); | 45 throw AdblockPlus::JsError(tryCatch.Exception(), tryCatch.Message()); |
45 } | 46 } |
46 | 47 |
47 class V8Initializer | 48 class V8Initializer |
48 { | 49 { |
49 V8Initializer() | 50 V8Initializer() |
50 { | 51 : platform(v8::platform::CreateDefaultPlatform()) |
| 52 { |
| 53 v8::V8::InitializePlatform(platform); |
51 v8::V8::Initialize(); | 54 v8::V8::Initialize(); |
52 } | 55 } |
53 | 56 |
54 ~V8Initializer() | 57 ~V8Initializer() |
55 { | 58 { |
56 v8::V8::Dispose(); | 59 v8::V8::Dispose(); |
57 } | 60 v8::V8::ShutdownPlatform(); |
| 61 delete platform; |
| 62 } |
| 63 v8::Platform* platform; |
58 public: | 64 public: |
59 static void Init() | 65 static void Init() |
60 { | 66 { |
61 // it's threadsafe since C++11 and it will be instantiated only once and | 67 // it's threadsafe since C++11 and it will be instantiated only once and |
62 // destroyed at the application exit | 68 // destroyed at the application exit |
63 static V8Initializer initializer; | 69 static V8Initializer initializer; |
64 } | 70 } |
65 }; | 71 }; |
66 } | 72 } |
67 | 73 |
(...skipping 10 matching lines...) Expand all Loading... |
78 } | 84 } |
79 | 85 |
80 WebRequestPtr AdblockPlus::CreateDefaultWebRequest() | 86 WebRequestPtr AdblockPlus::CreateDefaultWebRequest() |
81 { | 87 { |
82 return WebRequestPtr(new DefaultWebRequest(std::make_shared<DefaultWebRequestS
ync>())); | 88 return WebRequestPtr(new DefaultWebRequest(std::make_shared<DefaultWebRequestS
ync>())); |
83 } | 89 } |
84 | 90 |
85 AdblockPlus::ScopedV8Isolate::ScopedV8Isolate() | 91 AdblockPlus::ScopedV8Isolate::ScopedV8Isolate() |
86 { | 92 { |
87 V8Initializer::Init(); | 93 V8Initializer::Init(); |
88 isolate = v8::Isolate::New(); | 94 v8::Isolate::CreateParams isolateParams; |
| 95 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultA
llocator(); |
| 96 isolate = v8::Isolate::New(isolateParams); |
89 } | 97 } |
90 | 98 |
91 AdblockPlus::ScopedV8Isolate::~ScopedV8Isolate() | 99 AdblockPlus::ScopedV8Isolate::~ScopedV8Isolate() |
92 { | 100 { |
93 isolate->Dispose(); | 101 isolate->Dispose(); |
94 isolate = nullptr; | 102 isolate = nullptr; |
95 } | 103 } |
96 | 104 |
97 JsEngine::JsWeakValuesList::~JsWeakValuesList() | 105 JsEngine::JsWeakValuesList::~JsWeakValuesList() |
98 { | 106 { |
99 for (auto& value : values) | |
100 value->Dispose(); | |
101 } | 107 } |
102 | 108 |
103 void JsEngine::NotifyLowMemory() | 109 void JsEngine::NotifyLowMemory() |
104 { | 110 { |
105 const JsContext context(*this); | 111 const JsContext context(*this); |
106 v8::V8::LowMemoryNotification(); | 112 GetIsolate()->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical); |
107 } | 113 } |
108 | 114 |
109 void JsEngine::ScheduleTimer(const v8::Arguments& arguments) | 115 void JsEngine::ScheduleTimer(const v8::FunctionCallbackInfo<v8::Value>& argument
s) |
110 { | 116 { |
111 auto jsEngine = FromArguments(arguments); | 117 auto jsEngine = FromArguments(arguments); |
112 if (arguments.Length() < 2) | 118 if (arguments.Length() < 2) |
113 throw std::runtime_error("setTimeout requires at least 2 parameters"); | 119 throw std::runtime_error("setTimeout requires at least 2 parameters"); |
114 | 120 |
115 if (!arguments[0]->IsFunction()) | 121 if (!arguments[0]->IsFunction()) |
116 throw std::runtime_error("First argument to setTimeout must be a function"); | 122 throw std::runtime_error("First argument to setTimeout must be a function"); |
117 | 123 |
118 auto jsValueArguments = jsEngine->ConvertArguments(arguments); | 124 auto jsValueArguments = jsEngine->ConvertArguments(arguments); |
119 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); | 125 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); |
(...skipping 29 matching lines...) Expand all Loading... |
149 TimerPtr timer, FileSystemPtr fileSystem, WebRequestPtr webRequest) | 155 TimerPtr timer, FileSystemPtr fileSystem, WebRequestPtr webRequest) |
150 { | 156 { |
151 JsEnginePtr result(new JsEngine(std::move(timer), | 157 JsEnginePtr result(new JsEngine(std::move(timer), |
152 std::move(fileSystem), | 158 std::move(fileSystem), |
153 std::move(webRequest))); | 159 std::move(webRequest))); |
154 | 160 |
155 const v8::Locker locker(result->GetIsolate()); | 161 const v8::Locker locker(result->GetIsolate()); |
156 const v8::Isolate::Scope isolateScope(result->GetIsolate()); | 162 const v8::Isolate::Scope isolateScope(result->GetIsolate()); |
157 const v8::HandleScope handleScope(result->GetIsolate()); | 163 const v8::HandleScope handleScope(result->GetIsolate()); |
158 | 164 |
159 result->context.reset(new v8::Persistent<v8::Context>(result->GetIsolate(), | 165 result->context.reset(new v8::Global<v8::Context>(result->GetIsolate(), |
160 v8::Context::New(result->GetIsolate()))); | 166 v8::Context::New(result->GetIsolate()))); |
161 auto global = result->GetGlobalObject(); | 167 auto global = result->GetGlobalObject(); |
162 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); | 168 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); |
163 return result; | 169 return result; |
164 } | 170 } |
165 | 171 |
166 AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject() | 172 AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject() |
167 { | 173 { |
168 JsContext context(*this); | 174 JsContext context(*this); |
169 return JsValue(shared_from_this(), context.GetV8Context()->Global()); | 175 return JsValue(shared_from_this(), context.GetV8Context()->Global()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 auto it = eventCallbacks.find(eventName); | 214 auto it = eventCallbacks.find(eventName); |
209 if (it == eventCallbacks.end()) | 215 if (it == eventCallbacks.end()) |
210 return; | 216 return; |
211 callback = it->second; | 217 callback = it->second; |
212 } | 218 } |
213 callback(move(params)); | 219 callback(move(params)); |
214 } | 220 } |
215 | 221 |
216 void AdblockPlus::JsEngine::Gc() | 222 void AdblockPlus::JsEngine::Gc() |
217 { | 223 { |
218 while (!v8::V8::IdleNotification()); | 224 while (!GetIsolate()->IdleNotification(1000)); |
219 } | 225 } |
220 | 226 |
221 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(const std::string& val) | 227 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(const std::string& val) |
222 { | 228 { |
223 const JsContext context(*this); | 229 const JsContext context(*this); |
224 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); | 230 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); |
225 } | 231 } |
226 | 232 |
227 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(int64_t val) | 233 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(int64_t val) |
228 { | 234 { |
229 const JsContext context(*this); | 235 const JsContext context(*this); |
230 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); | 236 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); |
231 } | 237 } |
232 | 238 |
233 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(bool val) | 239 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(bool val) |
234 { | 240 { |
235 const JsContext context(*this); | 241 const JsContext context(*this); |
236 return JsValue(shared_from_this(), v8::Boolean::New(val)); | 242 return JsValue(shared_from_this(), v8::Boolean::New(GetIsolate(), val)); |
237 } | 243 } |
238 | 244 |
239 AdblockPlus::JsValue AdblockPlus::JsEngine::NewObject() | 245 AdblockPlus::JsValue AdblockPlus::JsEngine::NewObject() |
240 { | 246 { |
241 const JsContext context(*this); | 247 const JsContext context(*this); |
242 return JsValue(shared_from_this(), v8::Object::New()); | 248 return JsValue(shared_from_this(), v8::Object::New(GetIsolate())); |
243 } | 249 } |
244 | 250 |
245 AdblockPlus::JsValue AdblockPlus::JsEngine::NewCallback( | 251 AdblockPlus::JsValue AdblockPlus::JsEngine::NewCallback( |
246 const v8::InvocationCallback& callback) | 252 const v8::FunctionCallback& callback) |
247 { | 253 { |
248 const JsContext context(*this); | 254 const JsContext context(*this); |
249 | 255 |
250 // Note: we are leaking this weak pointer, no obvious way to destroy it when | 256 // Note: we are leaking this weak pointer, no obvious way to destroy it when |
251 // it's no longer used | 257 // it's no longer used |
252 std::weak_ptr<JsEngine>* data = | 258 std::weak_ptr<JsEngine>* data = |
253 new std::weak_ptr<JsEngine>(shared_from_this()); | 259 new std::weak_ptr<JsEngine>(shared_from_this()); |
254 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback, | 260 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(GetIsolate()
, callback, |
255 v8::External::New(data)); | 261 v8::External::New(GetIsolate(), data)); |
256 return JsValue(shared_from_this(), templ->GetFunction()); | 262 return JsValue(shared_from_this(), templ->GetFunction()); |
257 } | 263 } |
258 | 264 |
259 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Argument
s& arguments) | 265 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Function
CallbackInfo<v8::Value>& arguments) |
260 { | 266 { |
261 const v8::Local<const v8::External> external = | 267 const v8::Local<const v8::External> external = |
262 v8::Local<const v8::External>::Cast(arguments.Data()); | 268 v8::Local<const v8::External>::Cast(arguments.Data()); |
263 std::weak_ptr<JsEngine>* data = | 269 std::weak_ptr<JsEngine>* data = |
264 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); | 270 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); |
265 JsEnginePtr result = data->lock(); | 271 JsEnginePtr result = data->lock(); |
266 if (!result) | 272 if (!result) |
267 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; | 273 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; |
268 return result; | 274 return result; |
269 } | 275 } |
270 | 276 |
271 JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) | 277 JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) |
272 { | 278 { |
273 JsWeakValuesLists::iterator it; | 279 JsWeakValuesLists::iterator it; |
274 { | 280 { |
275 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 281 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
276 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); | 282 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); |
277 } | 283 } |
278 { | 284 { |
279 JsContext context(*this); | 285 JsContext context(*this); |
280 for (const auto& value : values) | 286 for (const auto& value : values) |
281 { | 287 { |
282 it->values.emplace_back(new v8::Persistent<v8::Value>(GetIsolate(), value.
UnwrapValue())); | 288 it->values.emplace_back(GetIsolate(), value.UnwrapValue()); |
283 } | 289 } |
284 } | 290 } |
285 JsWeakValuesID retValue; | 291 JsWeakValuesID retValue; |
286 retValue.iterator = it; | 292 retValue.iterator = it; |
287 return retValue; | 293 return retValue; |
288 } | 294 } |
289 | 295 |
290 JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) | 296 JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) |
291 { | 297 { |
292 JsValueList retValue; | 298 JsValueList retValue; |
293 { | 299 { |
294 JsContext context(*this); | 300 JsContext context(*this); |
295 for (const auto& v8Value : id.iterator->values) | 301 for (const auto& v8Value : id.iterator->values) |
296 { | 302 { |
297 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), *v8Value))); | 303 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), v8Value))); |
298 } | 304 } |
299 } | 305 } |
300 { | 306 { |
301 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 307 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
302 jsWeakValuesLists.erase(id.iterator); | 308 jsWeakValuesLists.erase(id.iterator); |
303 } | 309 } |
304 return retValue; | 310 return retValue; |
305 } | 311 } |
306 | 312 |
307 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Argum
ents& arguments) | 313 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Funct
ionCallbackInfo<v8::Value>& arguments) |
308 { | 314 { |
309 const JsContext context(*this); | 315 const JsContext context(*this); |
310 JsValueList list; | 316 JsValueList list; |
311 for (int i = 0; i < arguments.Length(); i++) | 317 for (int i = 0; i < arguments.Length(); i++) |
312 list.push_back(JsValue(shared_from_this(), arguments[i])); | 318 list.push_back(JsValue(shared_from_this(), arguments[i])); |
313 return list; | 319 return list; |
314 } | 320 } |
315 | 321 |
316 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem() const | 322 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetAsyncFileSystem() const |
317 { | 323 { |
318 return fileSystem; | 324 return fileSystem; |
| 325 } |
| 326 |
| 327 void AdblockPlus::JsEngine::SetFileSystem(const AdblockPlus::FileSystemSyncPtr&
val) |
| 328 { |
| 329 if (!val) |
| 330 throw std::runtime_error("FileSystem cannot be null"); |
| 331 |
| 332 fileSystem.reset(new DefaultFileSystem(val)); |
319 } | 333 } |
320 | 334 |
321 void AdblockPlus::JsEngine::SetWebRequest(const AdblockPlus::WebRequestSharedPtr
& val) | 335 void AdblockPlus::JsEngine::SetWebRequest(const AdblockPlus::WebRequestSharedPtr
& val) |
322 { | 336 { |
323 if (!val) | 337 if (!val) |
324 throw std::runtime_error("WebRequest cannot be null"); | 338 throw std::runtime_error("WebRequest cannot be null"); |
325 | 339 |
326 webRequestLegacy = val; | 340 webRequestLegacy = val; |
327 } | 341 } |
328 | 342 |
(...skipping 10 matching lines...) Expand all Loading... |
339 logSystem = val; | 353 logSystem = val; |
340 } | 354 } |
341 | 355 |
342 | 356 |
343 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name, | 357 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name, |
344 const AdblockPlus::JsValue& value) | 358 const AdblockPlus::JsValue& value) |
345 { | 359 { |
346 auto global = GetGlobalObject(); | 360 auto global = GetGlobalObject(); |
347 global.SetProperty(name, value); | 361 global.SetProperty(name, value); |
348 } | 362 } |
LEFT | RIGHT |