| 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-2016 Eyeo GmbH |    3  * Copyright (C) 2006-2016 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 15 matching lines...) Expand all  Loading... | 
|   26 #include "JsEngineTransition.h" |   26 #include "JsEngineTransition.h" | 
|   27 #include "Scheduler.h" |   27 #include "Scheduler.h" | 
|   28 #include "Utils.h" |   28 #include "Utils.h" | 
|   29 #include "Value.h" |   29 #include "Value.h" | 
|   30  |   30  | 
|   31 using namespace AdblockPlus; |   31 using namespace AdblockPlus; | 
|   32  |   32  | 
|   33 namespace |   33 namespace | 
|   34 { |   34 { | 
|   35   class ReadTask |   35   class ReadTask | 
 |   36     : public TaskFunctionInterface | 
|   36   { |   37   { | 
|   37     /** |   38     /** | 
|   38      * Shared pointer keeps engine in existence for task thread. |   39      * Shared pointer keeps engine in existence for task thread. | 
|   39      */ |   40      */ | 
|   40     JsEnginePtr jsEngine; |   41     JsEngineInternal* engine; | 
|   41     std::string path; |   42     std::string path; | 
|   42     V8PersistentNG<v8::Function> callbackFunction; |   43     V8PersistentNG<v8::Function> callbackFunction; | 
|   43  |   44  | 
|   44   public: |   45   public: | 
|   45     ReadTask(JsEngineInternal* engine, const std::string& path, |   46     ReadTask(JsEngineInternal* engine, const std::string& path, | 
|   46       V8PersistentNG<v8::Function> callbackFunction) |   47       V8PersistentNG<v8::Function> callbackFunction) | 
|   47       : jsEngine(engine->shared_from_this()), path(path), |   48       : engine(engine), path(path), | 
|   48       callbackFunction(callbackFunction) |   49       callbackFunction(callbackFunction) | 
|   49     {} |   50     {} | 
|   50  |   51  | 
|   51     void operator()() |   52     void operator()() override | 
|   52     { |   53     { | 
|   53       JsEngineInternal* engine = ToInternal(jsEngine); |  | 
|   54       std::string content; |   54       std::string content; | 
|   55       std::string error; |   55       std::string error; | 
|   56       // Read operation is long-lived. Do not lock engine during it. |   56       // Read operation is long-lived. Do not lock engine during it. | 
|   57       try |   57       try | 
|   58       { |   58       { | 
|   59         std::shared_ptr<std::istream> stream = engine->GetFileSystem()->Read(pat
     h); |   59         std::shared_ptr<std::istream> stream = engine->GetFileSystem()->Read(pat
     h); | 
|   60         content = Utils::Slurp(*stream); |   60         content = Utils::Slurp(*stream); | 
|   61       } |   61       } | 
|   62       catch (std::exception& e) |   62       catch (std::exception& e) | 
|   63       { |   63       { | 
|   64         error = e.what(); |   64         error = e.what(); | 
|   65       } |   65       } | 
|   66       catch (...) |   66       catch (...) | 
|   67       { |   67       { | 
|   68         error = "Unknown error while reading from " + path; |   68         error = "Unknown error while reading from " + path; | 
|   69       } |   69       } | 
|   70       // Call back with the results of the read operation |   70       // Call back with the results of the read operation | 
|   71       V8ExecutionScope scope(engine); |   71       V8ExecutionScope scope(engine); | 
|   72       auto callbackArguments = v8::Object::New(); |   72       auto callbackArguments = v8::Object::New(); | 
|   73       callbackArguments->Set(engine->ToV8String("content"), engine->ToV8String(c
     ontent)); |   73       callbackArguments->Set(engine->ToV8String("content"), engine->ToV8String(c
     ontent)); | 
|   74       callbackArguments->Set(engine->ToV8String("error"), engine->ToV8String(err
     or)); |   74       callbackArguments->Set(engine->ToV8String("error"), engine->ToV8String(err
     or)); | 
|   75       auto args = AllocatedArray<v8::Local<v8::Value>>(1); |   75       auto args = AllocatedArray<v8::Local<v8::Value>>(1); | 
|   76       args[0] = callbackArguments; |   76       args[0] = callbackArguments; | 
|   77       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); |   77       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); | 
|   78     } |   78     } | 
|   79   }; |   79   }; | 
|   80  |   80  | 
|   81   class WriteTask |   81   class WriteTask | 
 |   82     : public TaskFunctionInterface | 
|   82   { |   83   { | 
|   83     /** |   84     /** | 
|   84      * Shared pointer keeps engine in existence for task thread. |   85      * Shared pointer keeps engine in existence for task thread. | 
|   85      */ |   86      */ | 
|   86     JsEnginePtr jsEngine; |   87     JsEngineInternal* engine; | 
|   87     std::string path; |   88     std::string path; | 
|   88     std::string content; |   89     std::string content; | 
|   89     V8PersistentNG<v8::Function> callbackFunction; |   90     V8PersistentNG<v8::Function> callbackFunction; | 
|   90   public: |   91   public: | 
|   91     WriteTask(JsEngineInternal* engine, |   92     WriteTask(JsEngineInternal* engine, | 
|   92       const std::string& path, const std::string& content, |   93       const std::string& path, const std::string& content, | 
|   93       V8PersistentNG<v8::Function> callbackFunction) |   94       V8PersistentNG<v8::Function> callbackFunction) | 
|   94       : jsEngine(engine->shared_from_this()), path(path), content(content), |   95       : engine(engine), path(path), content(content), | 
|   95       callbackFunction(callbackFunction) |   96       callbackFunction(callbackFunction) | 
|   96     {} |   97     {} | 
|   97  |   98  | 
|   98     void operator()() |   99     void operator()() override | 
|   99     { |  100     { | 
|  100       JsEngineInternal* engine = ToInternal(jsEngine); |  | 
|  101       std::string error; |  101       std::string error; | 
|  102       // Write operation is long-lived. Do not lock engine during it. |  102       // Write operation is long-lived. Do not lock engine during it. | 
|  103       try |  103       try | 
|  104       { |  104       { | 
|  105         std::shared_ptr<std::iostream> stream(new std::stringstream); |  105         std::shared_ptr<std::iostream> stream(new std::stringstream); | 
|  106         *stream << content; |  106         *stream << content; | 
|  107         engine->GetFileSystem()->Write(path, stream); |  107         engine->GetFileSystem()->Write(path, stream); | 
|  108       } |  108       } | 
|  109       catch (std::exception& e) |  109       catch (std::exception& e) | 
|  110       { |  110       { | 
|  111         error = e.what(); |  111         error = e.what(); | 
|  112       } |  112       } | 
|  113       catch (...) |  113       catch (...) | 
|  114       { |  114       { | 
|  115         error = "Unknown error while writing to " + path; |  115         error = "Unknown error while writing to " + path; | 
|  116       } |  116       } | 
|  117       // Apply the callback function |  117       // Apply the callback function | 
|  118       V8ExecutionScope scope(engine); |  118       V8ExecutionScope scope(engine); | 
|  119       auto args = AllocatedArray<v8::Local<v8::Value>>(1); |  119       auto args = AllocatedArray<v8::Local<v8::Value>>(1); | 
|  120       args[0] = engine->ToV8String(error); |  120       args[0] = engine->ToV8String(error); | 
|  121       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); |  121       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); | 
|  122     } |  122     } | 
|  123   }; |  123   }; | 
|  124  |  124  | 
|  125   class MoveTask |  125   class MoveTask | 
 |  126     : public TaskFunctionInterface | 
|  126   { |  127   { | 
|  127     /** |  128     /** | 
|  128      * Shared pointer keeps engine in existence for task thread. |  129      * Shared pointer keeps engine in existence for task thread. | 
|  129      */ |  130      */ | 
|  130     JsEnginePtr jsEngine; |  131     JsEngineInternal* engine; | 
|  131     std::string fromPath; |  132     std::string fromPath; | 
|  132     std::string toPath; |  133     std::string toPath; | 
|  133     V8PersistentNG<v8::Function> callbackFunction; |  134     V8PersistentNG<v8::Function> callbackFunction; | 
|  134  |  135  | 
|  135   public: |  136   public: | 
|  136     MoveTask(JsEngineInternal* engine, const std::string& fromPath, const std::s
     tring& toPath, |  137     MoveTask(JsEngineInternal* engine, const std::string& fromPath, const std::s
     tring& toPath, | 
|  137       V8PersistentNG<v8::Function> callbackFunction) |  138       V8PersistentNG<v8::Function> callbackFunction) | 
|  138       : jsEngine(engine->shared_from_this()), fromPath(fromPath), toPath(toPath)
     ,  |  139       : engine(engine), fromPath(fromPath), toPath(toPath), | 
|  139       callbackFunction(callbackFunction) |  140       callbackFunction(callbackFunction) | 
|  140     {} |  141     {} | 
|  141  |  142  | 
|  142     void operator()() |  143     void operator()() override | 
|  143     { |  144     { | 
|  144       JsEngineInternal* engine(ToInternal(jsEngine)); |  | 
|  145       std::string error; |  145       std::string error; | 
|  146       try |  146       try | 
|  147       { |  147       { | 
|  148         engine->GetFileSystem()->Move(fromPath, toPath); |  148         engine->GetFileSystem()->Move(fromPath, toPath); | 
|  149       } |  149       } | 
|  150       catch (std::exception& e) |  150       catch (std::exception& e) | 
|  151       { |  151       { | 
|  152         error = e.what(); |  152         error = e.what(); | 
|  153       } |  153       } | 
|  154       catch (...) |  154       catch (...) | 
|  155       { |  155       { | 
|  156         error = "Unknown error while moving " + fromPath + " to " + toPath; |  156         error = "Unknown error while moving " + fromPath + " to " + toPath; | 
|  157       } |  157       } | 
|  158       V8ExecutionScope scope(engine); |  158       V8ExecutionScope scope(engine); | 
|  159       auto args = AllocatedArray<v8::Local<v8::Value>>(1); |  159       auto args = AllocatedArray<v8::Local<v8::Value>>(1); | 
|  160       args[0] = engine->ToV8String(error); |  160       args[0] = engine->ToV8String(error); | 
|  161       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); |  161       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); | 
|  162     } |  162     } | 
|  163   }; |  163   }; | 
|  164  |  164  | 
|  165   class RemoveTask |  165   class RemoveTask | 
 |  166     : public TaskFunctionInterface | 
|  166   { |  167   { | 
|  167     /** |  168     /** | 
|  168      * Shared pointer keeps engine in existence for task thread. |  169      * Shared pointer keeps engine in existence for task thread. | 
|  169      */ |  170      */ | 
|  170     JsEnginePtr jsEngine; |  171     JsEngineInternal *engine; | 
|  171     std::string path; |  172     std::string path; | 
|  172     V8PersistentNG<v8::Function> callbackFunction; |  173     V8PersistentNG<v8::Function> callbackFunction; | 
|  173  |  174  | 
|  174   public: |  175   public: | 
|  175     RemoveTask(JsEngineInternal *engine, const std::string& path, |  176     RemoveTask(JsEngineInternal *engine, const std::string& path, | 
|  176       V8PersistentNG<v8::Function> callbackFunction) |  177       V8PersistentNG<v8::Function> callbackFunction) | 
|  177       : jsEngine(engine->shared_from_this()), path(path), |  178       : engine(engine), path(path), | 
|  178       callbackFunction(callbackFunction) |  179       callbackFunction(callbackFunction) | 
|  179     {} |  180     {} | 
|  180  |  181  | 
|  181     void operator()() |  182     void operator()() override | 
|  182     { |  183     { | 
|  183       JsEngineInternal* engine(ToInternal(jsEngine)); |  | 
|  184       std::string error; |  184       std::string error; | 
|  185       try |  185       try | 
|  186       { |  186       { | 
|  187         engine->GetFileSystem()->Remove(path); |  187         engine->GetFileSystem()->Remove(path); | 
|  188       } |  188       } | 
|  189       catch (std::exception& e) |  189       catch (std::exception& e) | 
|  190       { |  190       { | 
|  191         error = e.what(); |  191         error = e.what(); | 
|  192       } |  192       } | 
|  193       catch (...) |  193       catch (...) | 
|  194       { |  194       { | 
|  195         error = "Unknown error while removing " + path; |  195         error = "Unknown error while removing " + path; | 
|  196       } |  196       } | 
|  197       V8ExecutionScope scope(engine); |  197       V8ExecutionScope scope(engine); | 
|  198       auto args = AllocatedArray<v8::Local<v8::Value>>(1); |  198       auto args = AllocatedArray<v8::Local<v8::Value>>(1); | 
|  199       args[0] = engine->ToV8String(error); |  199       args[0] = engine->ToV8String(error); | 
|  200       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); |  200       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); | 
|  201     } |  201     } | 
|  202   }; |  202   }; | 
|  203  |  203  | 
|  204   class StatTask |  204   class StatTask | 
 |  205     : public TaskFunctionInterface | 
|  205   { |  206   { | 
|  206     /** |  207     /** | 
|  207      * Shared pointer keeps engine in existence for task thread. |  208      * Shared pointer keeps engine in existence for task thread. | 
|  208      */ |  209      */ | 
|  209     JsEnginePtr jsEngine; |  210     JsEngineInternal *engine; | 
|  210     std::string path; |  211     std::string path; | 
|  211     V8PersistentNG<v8::Function> callbackFunction; |  212     V8PersistentNG<v8::Function> callbackFunction; | 
|  212  |  213  | 
|  213   public: |  214   public: | 
|  214     StatTask(JsEngineInternal* engine, const std::string& path, |  215     StatTask(JsEngineInternal* engine, const std::string& path, | 
|  215       V8PersistentNG<v8::Function> callbackFunction) |  216       V8PersistentNG<v8::Function> callbackFunction) | 
|  216       : jsEngine(engine->shared_from_this()), path(path), |  217       : engine(engine), path(path), | 
|  217       callbackFunction(callbackFunction) |  218       callbackFunction(callbackFunction) | 
|  218     {} |  219     {} | 
|  219  |  220  | 
|  220     void operator()() |  221     void operator()() override | 
|  221     { |  222     { | 
|  222       JsEngineInternal* engine(ToInternal(jsEngine)); |  | 
|  223       std::string error; |  223       std::string error; | 
|  224       FileSystem::StatResult statResult; |  224       FileSystem::StatResult statResult; | 
|  225       try |  225       try | 
|  226       { |  226       { | 
|  227         statResult = engine->GetFileSystem()->Stat(path); |  227         statResult = engine->GetFileSystem()->Stat(path); | 
|  228       } |  228       } | 
|  229       catch (std::exception& e) |  229       catch (std::exception& e) | 
|  230       { |  230       { | 
|  231         error = e.what(); |  231         error = e.what(); | 
|  232       } |  232       } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  244       auto args = AllocatedArray<v8::Local<v8::Value>>(1); |  244       auto args = AllocatedArray<v8::Local<v8::Value>>(1); | 
|  245       args[0] = callbackArgument; |  245       args[0] = callbackArgument; | 
|  246       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); |  246       engine->ApplyFunction(callbackFunction.Get(engine->GetIsolate()), std::mov
     e(args)); | 
|  247     } |  247     } | 
|  248   }; |  248   }; | 
|  249 } |  249 } | 
|  250  |  250  | 
|  251 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) |  251 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) | 
|  252 { |  252 { | 
|  253   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  253   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  254   std::shared_ptr<ReadTask> readTask; |  | 
|  255   try |  254   try | 
|  256   { |  255   { | 
|  257     if (arguments.Length() != 2) |  256     if (arguments.Length() != 2) | 
|  258     { |  257     { | 
|  259       throw std::runtime_error("_fileSystem.read requires 2 parameters"); |  258       throw std::runtime_error("_fileSystem.read requires 2 parameters"); | 
|  260     } |  259     } | 
|  261     bool argumentIsString; |  260     bool argumentIsString; | 
|  262     std::string firstArgument; |  261     std::string firstArgument; | 
|  263     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  262     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  264     if (!argumentIsString) |  263     if (!argumentIsString) | 
|  265     { |  264     { | 
|  266       throw std::runtime_error("First argument to _fileSystem.read must be a str
     ing"); |  265       throw std::runtime_error("First argument to _fileSystem.read must be a str
     ing"); | 
|  267     } |  266     } | 
|  268     if (!arguments[1]->IsFunction()) |  267     if (!arguments[1]->IsFunction()) | 
|  269     { |  268     { | 
|  270       throw std::runtime_error("Second argument to _fileSystem.read must be a fu
     nction"); |  269       throw std::runtime_error("Second argument to _fileSystem.read must be a fu
     nction"); | 
|  271     } |  270     } | 
|  272     readTask = std::make_shared<ReadTask>(engine, firstArgument,  |  271     ReadTask readTask(engine, firstArgument, | 
|  273       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[1]))); |  272       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[1]))); | 
 |  273     // Run the task | 
 |  274     engine->ScheduleTask(std::move(readTask), ImmediateSingleUseThread); | 
 |  275     return v8::Undefined(); | 
|  274   } |  276   } | 
|  275   catch (const std::exception& e) |  277   catch (const std::exception& e) | 
|  276   { |  278   { | 
|  277     return v8::ThrowException(engine->ToV8String(e.what())); |  279     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  278   } |  280   } | 
|  279   // Run the task |  | 
|  280   engine->Schedule(AdblockPlus::MakeHeapFunction(readTask), AdblockPlus::Immedia
     teSingleUseThread); |  | 
|  281   return v8::Undefined(); |  | 
|  282 } |  281 } | 
|  283  |  282  | 
|  284 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) |  283 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) | 
|  285 { |  284 { | 
|  286   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  285   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  287   std::shared_ptr<WriteTask> writeTask; |  | 
|  288   try |  286   try | 
|  289   { |  287   { | 
|  290     v8::Isolate* isolate = arguments.GetIsolate(); |  | 
|  291  |  | 
|  292     if (arguments.Length() != 3) |  288     if (arguments.Length() != 3) | 
|  293     { |  289     { | 
|  294       throw std::exception("_fileSystem.write requires 3 parameters"); |  290       throw std::exception("_fileSystem.write requires 3 parameters"); | 
|  295     } |  291     } | 
|  296     bool argumentIsString; |  292     bool argumentIsString; | 
|  297     std::string firstArgument; |  293     std::string firstArgument; | 
|  298     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  294     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  299     if (!argumentIsString) |  295     if (!argumentIsString) | 
|  300     { |  296     { | 
|  301       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); |  297       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); | 
|  302     } |  298     } | 
|  303     std::string secondArgument; |  299     std::string secondArgument; | 
|  304     std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); |  300     std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); | 
|  305     if (!argumentIsString) |  301     if (!argumentIsString) | 
|  306     { |  302     { | 
|  307       throw std::runtime_error("Second argument to _fileSystem.write must be a s
     tring"); |  303       throw std::runtime_error("Second argument to _fileSystem.write must be a s
     tring"); | 
|  308     } |  304     } | 
|  309     if (!arguments[2]->IsFunction()) |  305     if (!arguments[2]->IsFunction()) | 
|  310     { |  306     { | 
|  311       throw std::runtime_error("Third argument to _fileSystem.write must be a fu
     nction"); |  307       throw std::runtime_error("Third argument to _fileSystem.write must be a fu
     nction"); | 
|  312     } |  308     } | 
|  313     writeTask = std::make_shared<WriteTask>(engine, firstArgument, secondArgumen
     t,  |  309     // Run the task | 
 |  310     WriteTask writeTask(engine, firstArgument, secondArgument, | 
|  314       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[2]))); |  311       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[2]))); | 
 |  312     engine->ScheduleTask(std::move(writeTask), ImmediateSingleUseThread); | 
 |  313     return v8::Undefined(); | 
|  315   } |  314   } | 
|  316   catch (const std::exception& e) |  315   catch (const std::exception& e) | 
|  317   { |  316   { | 
|  318     return v8::ThrowException(engine->ToV8String(e.what())); |  317     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  319   } |  318   } | 
|  320   engine->Schedule(AdblockPlus::MakeHeapFunction(writeTask), AdblockPlus::Immedi
     ateSingleUseThread); |  | 
|  321   return v8::Undefined(); |  | 
|  322 } |  319 } | 
|  323  |  320  | 
|  324 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) |  321 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) | 
|  325 { |  322 { | 
|  326   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  323   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  327   std::shared_ptr<MoveTask> moveTask; |  | 
|  328   std::string firstArgument, secondArgument; |  | 
|  329   try |  324   try | 
|  330   { |  325   { | 
|  331     if (arguments.Length() != 3) |  326     if (arguments.Length() != 3) | 
|  332     { |  327     { | 
|  333       throw std::runtime_error("_fileSystem.move requires 3 parameters"); |  328       throw std::runtime_error("_fileSystem.move requires 3 parameters"); | 
|  334     } |  329     } | 
|  335     bool argumentIsString; |  330     bool argumentIsString; | 
 |  331     std::string firstArgument, secondArgument; | 
|  336     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  332     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  337     if (!argumentIsString) |  333     if (!argumentIsString) | 
|  338     { |  334     { | 
|  339       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); |  335       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); | 
|  340     } |  336     } | 
|  341     std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); |  337     std::tie(argumentIsString, secondArgument) = ConvertString(arguments[1]); | 
|  342     if (!argumentIsString) |  338     if (!argumentIsString) | 
|  343     { |  339     { | 
|  344       throw std::runtime_error("Second argument to _fileSystem.write must be a s
     tring"); |  340       throw std::runtime_error("Second argument to _fileSystem.write must be a s
     tring"); | 
|  345     } |  341     } | 
|  346     if (!arguments[2]->IsFunction()) |  342     if (!arguments[2]->IsFunction()) | 
|  347     { |  343     { | 
|  348       throw std::runtime_error("Third argument to _fileSystem.move must be a fun
     ction"); |  344       throw std::runtime_error("Third argument to _fileSystem.move must be a fun
     ction"); | 
|  349     } |  345     } | 
 |  346     // Run the task | 
 |  347     MoveTask moveTask(engine, firstArgument, secondArgument, | 
 |  348       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[2]))); | 
 |  349     engine->ScheduleTask(std::move(moveTask), ImmediateSingleUseThread); | 
 |  350     return v8::Undefined(); | 
|  350   } |  351   } | 
|  351   catch (const std::exception& e) |  352   catch (const std::exception& e) | 
|  352   { |  353   { | 
|  353     return v8::ThrowException(engine->ToV8String(e.what())); |  354     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  354   } |  355   } | 
|  355   // Run the task |  | 
|  356   moveTask = std::make_shared<MoveTask>(engine, firstArgument, secondArgument,  |  | 
|  357     V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::
     Cast(arguments[2]))); |  | 
|  358   engine->Schedule(AdblockPlus::MakeHeapFunction(moveTask), AdblockPlus::Immedia
     teSingleUseThread); |  | 
|  359   return v8::Undefined(); |  | 
|  360 } |  356 } | 
|  361  |  357  | 
|  362 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) |  358 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) | 
|  363 { |  359 { | 
|  364   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  360   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  365   std::shared_ptr<RemoveTask> removeTask; |  | 
|  366   std::string firstArgument; |  | 
|  367   try |  361   try | 
|  368   { |  362   { | 
|  369     if (arguments.Length() != 2) |  363     if (arguments.Length() != 2) | 
|  370     { |  364     { | 
|  371       throw std::runtime_error("_fileSystem.remove requires 2 parameters"); |  365       throw std::runtime_error("_fileSystem.remove requires 2 parameters"); | 
|  372     } |  366     } | 
|  373     bool argumentIsString; |  367     bool argumentIsString; | 
 |  368     std::string firstArgument; | 
|  374     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  369     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  375     if (!argumentIsString) |  370     if (!argumentIsString) | 
|  376     { |  371     { | 
|  377       throw std::runtime_error("First argument to _fileSystem.remove must be a s
     tring"); |  372       throw std::runtime_error("First argument to _fileSystem.remove must be a s
     tring"); | 
|  378     } |  373     } | 
|  379     if (!arguments[1]->IsFunction()) |  374     if (!arguments[1]->IsFunction()) | 
|  380     { |  375     { | 
|  381       throw std::runtime_error("Second argument to _fileSystem.remove must be a 
     function"); |  376       throw std::runtime_error("Second argument to _fileSystem.remove must be a 
     function"); | 
|  382     } |  377     } | 
 |  378     // Run the task | 
 |  379     RemoveTask removeTask(engine, firstArgument, | 
 |  380       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[1]))); | 
 |  381     engine->ScheduleTask(std::move(removeTask), ImmediateSingleUseThread); | 
 |  382     return v8::Undefined(); | 
|  383   } |  383   } | 
|  384   catch (const std::exception& e) |  384   catch (const std::exception& e) | 
|  385   { |  385   { | 
|  386     return v8::ThrowException(engine->ToV8String(e.what())); |  386     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  387   } |  387   } | 
|  388   // Run the task |  | 
|  389   removeTask = std::make_shared<RemoveTask>(engine, firstArgument, |  | 
|  390     V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::
     Cast(arguments[1]))); |  | 
|  391   engine->Schedule(AdblockPlus::MakeHeapFunction(removeTask), AdblockPlus::Immed
     iateSingleUseThread); |  | 
|  392   return v8::Undefined(); |  | 
|  393 } |  388 } | 
|  394  |  389  | 
|  395 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) |  390 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) | 
|  396 { |  391 { | 
|  397   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  392   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  398   std::shared_ptr<StatTask> statTask; |  | 
|  399   std::string firstArgument; |  | 
|  400   try |  393   try | 
|  401   { |  394   { | 
|  402     if (arguments.Length() != 2) |  395     if (arguments.Length() != 2) | 
|  403     { |  396     { | 
|  404       throw std::runtime_error("_fileSystem.stat requires 2 parameters"); |  397       throw std::runtime_error("_fileSystem.stat requires 2 parameters"); | 
|  405     } |  398     } | 
|  406     bool argumentIsString; |  399     bool argumentIsString; | 
 |  400     std::string firstArgument; | 
|  407     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  401     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  408     if (!argumentIsString) |  402     if (!argumentIsString) | 
|  409     { |  403     { | 
|  410       throw std::runtime_error("First argument to _fileSystem.stat must be a str
     ing"); |  404       throw std::runtime_error("First argument to _fileSystem.stat must be a str
     ing"); | 
|  411     } |  405     } | 
|  412     if (!arguments[1]->IsFunction()) |  406     if (!arguments[1]->IsFunction()) | 
|  413     { |  407     { | 
|  414       throw std::runtime_error("Second argument to _fileSystem.stat must be a fu
     nction"); |  408       throw std::runtime_error("Second argument to _fileSystem.stat must be a fu
     nction"); | 
|  415     } |  409     } | 
 |  410     // Run the task | 
 |  411     StatTask statTask(engine, firstArgument, | 
 |  412       V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>
     ::Cast(arguments[1]))); | 
 |  413     engine->ScheduleTask(std::move(statTask), ImmediateSingleUseThread); | 
 |  414     return v8::Undefined(); | 
|  416   } |  415   } | 
|  417   catch (const std::exception& e) |  416   catch (const std::exception& e) | 
|  418   { |  417   { | 
|  419     return v8::ThrowException(engine->ToV8String(e.what())); |  418     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  420   } |  419   } | 
|  421   // Run the task |  | 
|  422   statTask = std::make_shared<StatTask>(engine, firstArgument, |  | 
|  423     V8PersistentNG<v8::Function>(engine->GetIsolate(), v8::Local<v8::Function>::
     Cast(arguments[1]))); |  | 
|  424   engine->Schedule(AdblockPlus::MakeHeapFunction(statTask), AdblockPlus::Immedia
     teSingleUseThread); |  | 
|  425   return v8::Undefined(); |  | 
|  426 } |  420 } | 
|  427  |  421  | 
|  428 v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) |  422 v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) | 
|  429 { |  423 { | 
|  430   auto engine(JsEngineInternal::ExtractEngine(arguments)); |  424   auto engine(JsEngineInternal::ExtractEngine(arguments)); | 
|  431   std::string firstArgument; |  425   std::string firstArgument; | 
|  432   try |  426   try | 
|  433   { |  427   { | 
|  434     if (arguments.Length() != 1) |  428     if (arguments.Length() != 1) | 
|  435     { |  429     { | 
|  436       throw std::runtime_error("_fileSystem.resolve requires 1 parameter"); |  430       throw std::runtime_error("_fileSystem.resolve requires 1 parameter"); | 
|  437     } |  431     } | 
|  438     bool argumentIsString; |  432     bool argumentIsString; | 
|  439     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); |  433     std::tie(argumentIsString, firstArgument) = ConvertString(arguments[0]); | 
|  440     if (!argumentIsString) |  434     if (!argumentIsString) | 
|  441     { |  435     { | 
|  442       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); |  436       throw std::runtime_error("First argument to _fileSystem.write must be a st
     ring"); | 
|  443     } |  437     } | 
|  444   } |  438   } | 
|  445   catch (const std::exception& e) |  439   catch (const std::exception& e) | 
|  446   { |  440   { | 
|  447     return v8::ThrowException(engine->ToV8String(e.what())); |  441     return v8::ThrowException(engine->ToV8String(e.what())); | 
|  448   } |  442   } | 
|  449   /* |  443   /* | 
|  450    * Make sure to perform long-lived file system operation with engine unlocked. |  444    * Make sure to perform long-lived file system operation with engine unlocked. | 
|  451    */ |  445    */ | 
|  452   std::string resolved = engine->GetFileSystem()->Resolve(firstArgument); |  446   std::string resolved = engine->GetFileSystem()->Resolve(firstArgument); | 
|  453   return engine->ToV8String(resolved); |  447   return engine->ToV8String(resolved); | 
|  454 } |  448 } | 
| OLD | NEW |