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