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-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() |
| 51 : platform(v8::platform::CreateDefaultPlatform()) |
50 { | 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(); |
| 60 v8::V8::ShutdownPlatform(); |
| 61 delete platform; |
57 } | 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 |
68 using namespace AdblockPlus; | 74 using namespace AdblockPlus; |
69 | 75 |
70 TimerPtr AdblockPlus::CreateDefaultTimer() | 76 TimerPtr AdblockPlus::CreateDefaultTimer() |
71 { | 77 { |
72 return TimerPtr(new DefaultTimer()); | 78 return TimerPtr(new DefaultTimer()); |
73 } | 79 } |
74 | 80 |
75 WebRequestPtr AdblockPlus::CreateDefaultWebRequest() | 81 WebRequestPtr AdblockPlus::CreateDefaultWebRequest() |
76 { | 82 { |
77 return WebRequestPtr(new DefaultWebRequest(std::make_shared<DefaultWebRequestS
ync>())); | 83 return WebRequestPtr(new DefaultWebRequest(std::make_shared<DefaultWebRequestS
ync>())); |
78 } | 84 } |
79 | 85 |
80 AdblockPlus::ScopedV8Isolate::ScopedV8Isolate() | 86 AdblockPlus::ScopedV8Isolate::ScopedV8Isolate() |
81 { | 87 { |
82 V8Initializer::Init(); | 88 V8Initializer::Init(); |
83 isolate = v8::Isolate::New(); | 89 v8::Isolate::CreateParams isolateParams; |
| 90 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultA
llocator(); |
| 91 isolate = v8::Isolate::New(isolateParams); |
84 } | 92 } |
85 | 93 |
86 AdblockPlus::ScopedV8Isolate::~ScopedV8Isolate() | 94 AdblockPlus::ScopedV8Isolate::~ScopedV8Isolate() |
87 { | 95 { |
88 isolate->Dispose(); | 96 isolate->Dispose(); |
89 isolate = nullptr; | 97 isolate = nullptr; |
90 } | 98 } |
91 | 99 |
92 JsEngine::JsWeakValuesList::~JsWeakValuesList() | 100 JsEngine::JsWeakValuesList::~JsWeakValuesList() |
93 { | 101 { |
94 for (auto& value : values) | |
95 value->Dispose(); | |
96 } | 102 } |
97 | 103 |
98 void JsEngine::NotifyLowMemory() | 104 void JsEngine::NotifyLowMemory() |
99 { | 105 { |
100 const JsContext context(*this); | 106 const JsContext context(*this); |
101 v8::V8::LowMemoryNotification(); | 107 GetIsolate()->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical); |
102 } | 108 } |
103 | 109 |
104 void JsEngine::ScheduleTimer(const v8::Arguments& arguments) | 110 void JsEngine::ScheduleTimer(const v8::FunctionCallbackInfo<v8::Value>& argument
s) |
105 { | 111 { |
106 auto jsEngine = FromArguments(arguments); | 112 auto jsEngine = FromArguments(arguments); |
107 if (arguments.Length() < 2) | 113 if (arguments.Length() < 2) |
108 throw std::runtime_error("setTimeout requires at least 2 parameters"); | 114 throw std::runtime_error("setTimeout requires at least 2 parameters"); |
109 | 115 |
110 if (!arguments[0]->IsFunction()) | 116 if (!arguments[0]->IsFunction()) |
111 throw std::runtime_error("First argument to setTimeout must be a function"); | 117 throw std::runtime_error("First argument to setTimeout must be a function"); |
112 | 118 |
113 auto jsValueArguments = jsEngine->ConvertArguments(arguments); | 119 auto jsValueArguments = jsEngine->ConvertArguments(arguments); |
114 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); | 120 auto timerParamsID = jsEngine->StoreJsValues(jsValueArguments); |
(...skipping 26 matching lines...) Expand all Loading... |
141 | 147 |
142 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo, | 148 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo, |
143 TimerPtr timer, WebRequestPtr webRequest) | 149 TimerPtr timer, WebRequestPtr webRequest) |
144 { | 150 { |
145 JsEnginePtr result(new JsEngine(std::move(timer), std::move(webRequest))); | 151 JsEnginePtr result(new JsEngine(std::move(timer), std::move(webRequest))); |
146 | 152 |
147 const v8::Locker locker(result->GetIsolate()); | 153 const v8::Locker locker(result->GetIsolate()); |
148 const v8::Isolate::Scope isolateScope(result->GetIsolate()); | 154 const v8::Isolate::Scope isolateScope(result->GetIsolate()); |
149 const v8::HandleScope handleScope(result->GetIsolate()); | 155 const v8::HandleScope handleScope(result->GetIsolate()); |
150 | 156 |
151 result->context.reset(new v8::Persistent<v8::Context>(result->GetIsolate(), | 157 result->context.reset(new v8::Global<v8::Context>(result->GetIsolate(), |
152 v8::Context::New(result->GetIsolate()))); | 158 v8::Context::New(result->GetIsolate()))); |
153 auto global = result->GetGlobalObject(); | 159 auto global = result->GetGlobalObject(); |
154 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); | 160 AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global); |
155 return result; | 161 return result; |
156 } | 162 } |
157 | 163 |
158 AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject() | 164 AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject() |
159 { | 165 { |
160 JsContext context(*this); | 166 JsContext context(*this); |
161 return JsValue(shared_from_this(), context.GetV8Context()->Global()); | 167 return JsValue(shared_from_this(), context.GetV8Context()->Global()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 auto it = eventCallbacks.find(eventName); | 206 auto it = eventCallbacks.find(eventName); |
201 if (it == eventCallbacks.end()) | 207 if (it == eventCallbacks.end()) |
202 return; | 208 return; |
203 callback = it->second; | 209 callback = it->second; |
204 } | 210 } |
205 callback(move(params)); | 211 callback(move(params)); |
206 } | 212 } |
207 | 213 |
208 void AdblockPlus::JsEngine::Gc() | 214 void AdblockPlus::JsEngine::Gc() |
209 { | 215 { |
210 while (!v8::V8::IdleNotification()); | 216 while (!GetIsolate()->IdleNotification(1000)); |
211 } | 217 } |
212 | 218 |
213 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(const std::string& val) | 219 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(const std::string& val) |
214 { | 220 { |
215 const JsContext context(*this); | 221 const JsContext context(*this); |
216 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); | 222 return JsValue(shared_from_this(), Utils::ToV8String(GetIsolate(), val)); |
217 } | 223 } |
218 | 224 |
219 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(int64_t val) | 225 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(int64_t val) |
220 { | 226 { |
221 const JsContext context(*this); | 227 const JsContext context(*this); |
222 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); | 228 return JsValue(shared_from_this(), v8::Number::New(GetIsolate(), val)); |
223 } | 229 } |
224 | 230 |
225 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(bool val) | 231 AdblockPlus::JsValue AdblockPlus::JsEngine::NewValue(bool val) |
226 { | 232 { |
227 const JsContext context(*this); | 233 const JsContext context(*this); |
228 return JsValue(shared_from_this(), v8::Boolean::New(val)); | 234 return JsValue(shared_from_this(), v8::Boolean::New(GetIsolate(), val)); |
229 } | 235 } |
230 | 236 |
231 AdblockPlus::JsValue AdblockPlus::JsEngine::NewObject() | 237 AdblockPlus::JsValue AdblockPlus::JsEngine::NewObject() |
232 { | 238 { |
233 const JsContext context(*this); | 239 const JsContext context(*this); |
234 return JsValue(shared_from_this(), v8::Object::New()); | 240 return JsValue(shared_from_this(), v8::Object::New(GetIsolate())); |
235 } | 241 } |
236 | 242 |
237 AdblockPlus::JsValue AdblockPlus::JsEngine::NewCallback( | 243 AdblockPlus::JsValue AdblockPlus::JsEngine::NewCallback( |
238 const v8::InvocationCallback& callback) | 244 const v8::FunctionCallback& callback) |
239 { | 245 { |
240 const JsContext context(*this); | 246 const JsContext context(*this); |
241 | 247 |
242 // Note: we are leaking this weak pointer, no obvious way to destroy it when | 248 // Note: we are leaking this weak pointer, no obvious way to destroy it when |
243 // it's no longer used | 249 // it's no longer used |
244 std::weak_ptr<JsEngine>* data = | 250 std::weak_ptr<JsEngine>* data = |
245 new std::weak_ptr<JsEngine>(shared_from_this()); | 251 new std::weak_ptr<JsEngine>(shared_from_this()); |
246 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback, | 252 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(GetIsolate()
, callback, |
247 v8::External::New(data)); | 253 v8::External::New(GetIsolate(), data)); |
248 return JsValue(shared_from_this(), templ->GetFunction()); | 254 return JsValue(shared_from_this(), templ->GetFunction()); |
249 } | 255 } |
250 | 256 |
251 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Argument
s& arguments) | 257 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Function
CallbackInfo<v8::Value>& arguments) |
252 { | 258 { |
253 const v8::Local<const v8::External> external = | 259 const v8::Local<const v8::External> external = |
254 v8::Local<const v8::External>::Cast(arguments.Data()); | 260 v8::Local<const v8::External>::Cast(arguments.Data()); |
255 std::weak_ptr<JsEngine>* data = | 261 std::weak_ptr<JsEngine>* data = |
256 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); | 262 static_cast<std::weak_ptr<JsEngine>*>(external->Value()); |
257 JsEnginePtr result = data->lock(); | 263 JsEnginePtr result = data->lock(); |
258 if (!result) | 264 if (!result) |
259 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; | 265 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?")
; |
260 return result; | 266 return result; |
261 } | 267 } |
262 | 268 |
263 JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) | 269 JsEngine::JsWeakValuesID JsEngine::StoreJsValues(const JsValueList& values) |
264 { | 270 { |
265 JsWeakValuesLists::iterator it; | 271 JsWeakValuesLists::iterator it; |
266 { | 272 { |
267 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 273 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
268 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); | 274 it = jsWeakValuesLists.emplace(jsWeakValuesLists.end()); |
269 } | 275 } |
270 { | 276 { |
271 JsContext context(*this); | 277 JsContext context(*this); |
272 for (const auto& value : values) | 278 for (const auto& value : values) |
273 { | 279 { |
274 it->values.emplace_back(new v8::Persistent<v8::Value>(GetIsolate(), value.
UnwrapValue())); | 280 it->values.emplace_back(GetIsolate(), value.UnwrapValue()); |
275 } | 281 } |
276 } | 282 } |
277 JsWeakValuesID retValue; | 283 JsWeakValuesID retValue; |
278 retValue.iterator = it; | 284 retValue.iterator = it; |
279 return retValue; | 285 return retValue; |
280 } | 286 } |
281 | 287 |
282 JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) | 288 JsValueList JsEngine::TakeJsValues(const JsWeakValuesID& id) |
283 { | 289 { |
284 JsValueList retValue; | 290 JsValueList retValue; |
285 { | 291 { |
286 JsContext context(*this); | 292 JsContext context(*this); |
287 for (const auto& v8Value : id.iterator->values) | 293 for (const auto& v8Value : id.iterator->values) |
288 { | 294 { |
289 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), *v8Value))); | 295 retValue.emplace_back(JsValue(shared_from_this(), v8::Local<v8::Value>::Ne
w(GetIsolate(), v8Value))); |
290 } | 296 } |
291 } | 297 } |
292 { | 298 { |
293 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); | 299 std::lock_guard<std::mutex> lock(jsWeakValuesListsMutex); |
294 jsWeakValuesLists.erase(id.iterator); | 300 jsWeakValuesLists.erase(id.iterator); |
295 } | 301 } |
296 return retValue; | 302 return retValue; |
297 } | 303 } |
298 | 304 |
299 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Argum
ents& arguments) | 305 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Funct
ionCallbackInfo<v8::Value>& arguments) |
300 { | 306 { |
301 const JsContext context(*this); | 307 const JsContext context(*this); |
302 JsValueList list; | 308 JsValueList list; |
303 for (int i = 0; i < arguments.Length(); i++) | 309 for (int i = 0; i < arguments.Length(); i++) |
304 list.push_back(JsValue(shared_from_this(), arguments[i])); | 310 list.push_back(JsValue(shared_from_this(), arguments[i])); |
305 return list; | 311 return list; |
306 } | 312 } |
307 | 313 |
308 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem() const | 314 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem() const |
309 { | 315 { |
(...skipping 29 matching lines...) Expand all Loading... |
339 logSystem = val; | 345 logSystem = val; |
340 } | 346 } |
341 | 347 |
342 | 348 |
343 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name, | 349 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name, |
344 const AdblockPlus::JsValue& value) | 350 const AdblockPlus::JsValue& value) |
345 { | 351 { |
346 auto global = GetGlobalObject(); | 352 auto global = GetGlobalObject(); |
347 global.SetProperty(name, value); | 353 global.SetProperty(name, value); |
348 } | 354 } |
OLD | NEW |