| 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 |