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

Delta Between Two Patch Sets: src/GlobalJsObject.cpp

Issue 10085006: Implement setTimeout (Closed)
Left Patch Set: Created April 5, 2013, 3:49 p.m.
Right Patch Set: Created April 8, 2013, 1:07 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « libadblockplus.gyp ('k') | src/JsEngine.cpp » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #include <vector> 1 #include <vector>
2 #include <stdexcept>
2 3
3 #include "GlobalJsObject.h" 4 #include "GlobalJsObject.h"
4 #include "Thread.h" 5 #include "Thread.h"
5 6
6 using namespace AdblockPlus; 7 using namespace AdblockPlus;
7 8
8 namespace 9 namespace
9 { 10 {
10 class TimeoutThread : public Thread 11 class TimeoutThread : public Thread
11 { 12 {
12 public: 13 public:
13 TimeoutThread(v8::Isolate* const isolate, const v8::Arguments& arguments) 14 TimeoutThread(v8::Isolate* const isolate, const v8::Arguments& arguments)
14 : isolate(isolate) 15 : isolate(isolate)
15 { 16 {
17 if (arguments.Length() < 2)
18 throw std::runtime_error("setTimeout requires at least 2 parameters");
19
20 const v8::Local<v8::Value> functionValue = arguments[0];
21 if (!functionValue->IsFunction())
22 throw std::runtime_error("No valid function passed to setTimeout");
Wladimir Palant 2013/04/08 14:03:47 Nit: I think the canonical message is: "First argu
23
24 const v8::Local<v8::Value> delayValue = arguments[1];
25 if (!delayValue->IsNumber())
26 throw std::runtime_error("No valid delay passed to setTimeout");
Wladimir Palant 2013/04/08 14:03:47 Nit: I think the canonical message is: "Second arg
27
16 function = v8::Persistent<v8::Function>::New( 28 function = v8::Persistent<v8::Function>::New(
17 isolate, v8::Local<v8::Function>::Cast(arguments[0])); 29 isolate, v8::Local<v8::Function>::Cast(functionValue));
Felix Dahlke 2013/04/08 13:07:49 Phew, good find. V8 isn't exactly documented but I
18 delay = arguments[1]->ToNumber()->Value(); 30 delay = delayValue->ToNumber()->Value();
19 for (int i = 2; i < arguments.Length(); i++) 31 for (int i = 2; i < arguments.Length(); i++)
20 { 32 {
21 const Value argument = Value::New(isolate, arguments[i]); 33 const Value argument = Value::New(isolate, arguments[i]);
22 functionArguments.push_back(argument); 34 functionArguments.push_back(argument);
23 } 35 }
24 } 36 }
25 37
26 ~TimeoutThread() 38 ~TimeoutThread()
27 { 39 {
28 function.Dispose(isolate); 40 function.Dispose(isolate);
29 for (Values::iterator it = functionArguments.begin(); 41 for (Values::iterator it = functionArguments.begin();
30 it != functionArguments.end(); it++) 42 it != functionArguments.end(); it++)
31 it->Dispose(isolate); 43 it->Dispose(isolate);
32 } 44 }
33 45
34 void Run() 46 void Run()
35 { 47 {
36 Sleep(delay); 48 Sleep(delay);
37 const v8::Locker locker(isolate); 49 const v8::Locker locker(isolate);
Wladimir Palant 2013/04/08 08:36:00 Does this really lock when this line is reached or
38 const v8::HandleScope handleScope; 50 const v8::HandleScope handleScope;
39 function->Call(function, functionArguments.size(), &functionArguments[0]); 51 function->Call(function, functionArguments.size(), &functionArguments[0]);
40 delete this; 52 delete this;
Wladimir Palant 2013/04/08 08:36:00 Self-deleting object? 1) Is that a good practice?
Felix Dahlke 2013/04/08 13:07:49 1) Depends. It's not generally considered a bad pr
Wladimir Palant 2013/04/08 14:03:47 I checked, delete is actually thread-safe - so no
41 } 53 }
42 54
43 private: 55 private:
44 typedef v8::Persistent<v8::Value> Value; 56 typedef v8::Persistent<v8::Value> Value;
45 typedef std::vector<Value> Values; 57 typedef std::vector<Value> Values;
46 58
47 v8::Isolate* const isolate; 59 v8::Isolate* const isolate;
48 v8::Persistent<v8::Function> function; 60 v8::Persistent<v8::Function> function;
49 int delay; 61 int delay;
50 Values functionArguments; 62 Values functionArguments;
51 }; 63 };
52 64
53 v8::Handle<v8::Value> SetTimeoutCallback(const v8::Arguments& arguments) 65 v8::Handle<v8::Value> SetTimeoutCallback(const v8::Arguments& arguments)
54 { 66 {
55 TimeoutThread* const timeoutThread = 67 TimeoutThread* timeoutThread;
56 new TimeoutThread(v8::Isolate::GetCurrent(), arguments); 68 try
69 {
70 timeoutThread = new TimeoutThread(v8::Isolate::GetCurrent(), arguments);
71 }
72 catch (const std::exception& e)
73 {
74 return v8::ThrowException(v8::String::New(e.what()));
75 }
57 timeoutThread->Start(); 76 timeoutThread->Start();
58 77
59 // We should actually return the timer ID here, which could be 78 // We should actually return the timer ID here, which could be
60 // used via clearTimeout(). But since we don't seem to need 79 // used via clearTimeout(). But since we don't seem to need
61 // clearTimeout(), we can safe that for later. 80 // clearTimeout(), we can save that for later.
Wladimir Palant 2013/04/08 08:36:00 safe => save?
Felix Dahlke 2013/04/08 13:07:49 Yes, of course.
62 return v8::Undefined(); 81 return v8::Undefined();
63 } 82 }
64 } 83 }
65 84
66 v8::Handle<v8::ObjectTemplate> GlobalJsObject::Create( 85 v8::Handle<v8::ObjectTemplate> GlobalJsObject::Create(
67 ErrorCallback& errorCallback) 86 ErrorCallback& errorCallback)
68 { 87 {
69 const v8::Locker locker(v8::Isolate::GetCurrent()); 88 const v8::Locker locker(v8::Isolate::GetCurrent());
70 v8::HandleScope handleScope; 89 v8::HandleScope handleScope;
71 const v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 90 const v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
72 const v8::Handle<v8::ObjectTemplate> console = 91 const v8::Handle<v8::ObjectTemplate> console =
73 AdblockPlus::ConsoleJsObject::Create(errorCallback); 92 AdblockPlus::ConsoleJsObject::Create(errorCallback);
74 global->Set(v8::String::New("console"), console); 93 global->Set(v8::String::New("console"), console);
75 const v8::Handle<v8::FunctionTemplate> setTimeoutFunction = 94 const v8::Handle<v8::FunctionTemplate> setTimeoutFunction =
76 v8::FunctionTemplate::New(SetTimeoutCallback); 95 v8::FunctionTemplate::New(SetTimeoutCallback);
77 global->Set(v8::String::New("setTimeout"), setTimeoutFunction); 96 global->Set(v8::String::New("setTimeout"), setTimeoutFunction);
78 return handleScope.Close(global); 97 return handleScope.Close(global);
79 } 98 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld