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

Side by Side Diff: src/FileSystemJsObject.cpp

Issue 29369557: Issue #4692 - Rewrite I/O tasks to avoid engine self-reference
Patch Set: Created Dec. 28, 2016, 5:34 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/FileSystemJsObject.h ('k') | src/GlobalJsObject.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-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 }
OLDNEW
« no previous file with comments | « src/FileSystemJsObject.h ('k') | src/GlobalJsObject.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld