Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/JsEngine.cpp

Issue 29661564: Template out V8 and prepare for other JS engine implementations
Patch Set: Created Jan. 10, 2018, 1:29 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/JsContext.cpp ('k') | src/JsValue.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 }
OLDNEW
« no previous file with comments | « src/JsContext.cpp ('k') | src/JsValue.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld