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

Side by Side Diff: src/JsEngine.cpp

Issue 10173031: Don`t use references to JsEngine to avoid use-after-free errors,switch to shared_ptr instead (Closed)
Patch Set: Created April 18, 2013, 4:15 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/GlobalJsObject.cpp ('k') | src/JsValue.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 #include <AdblockPlus.h> 1 #include <AdblockPlus.h>
2 #include <sstream> 2 #include <sstream>
3 3
4 #include "GlobalJsObject.h" 4 #include "GlobalJsObject.h"
5 #include "Utils.h" 5 #include "Utils.h"
6 6
7 namespace 7 namespace
8 { 8 {
9 v8::Handle<v8::Script> CompileScript(const std::string& source, const std::str ing& filename) 9 v8::Handle<v8::Script> CompileScript(const std::string& source, const std::str ing& filename)
10 { 10 {
(...skipping 28 matching lines...) Expand all
39 return error.str(); 39 return error.str();
40 } 40 }
41 } 41 }
42 42
43 AdblockPlus::JsError::JsError(const v8::Handle<v8::Value> exception, 43 AdblockPlus::JsError::JsError(const v8::Handle<v8::Value> exception,
44 const v8::Handle<v8::Message> message) 44 const v8::Handle<v8::Message> message)
45 : std::runtime_error(ExceptionToString(exception, message)) 45 : std::runtime_error(ExceptionToString(exception, message))
46 { 46 {
47 } 47 }
48 48
49 AdblockPlus::JsEngine::JsEngine(const AppInfo& appInfo) 49 AdblockPlus::JsEngine::JsEngine()
50 : isolate(v8::Isolate::GetCurrent()) 50 : isolate(v8::Isolate::GetCurrent())
51 { 51 {
52 const v8::Locker locker(isolate); 52 }
53
54 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo)
Felix Dahlke 2013/04/18 18:42:16 I don't think we should have this. "JsEnginePtr x(
Wladimir Palant 2013/04/18 20:24:28 We need to have the object in a shared_ptr before
55 {
56 JsEnginePtr result(new JsEngine());
57
58 const v8::Locker locker(result->isolate);
Felix Dahlke 2013/04/18 18:42:16 This is initialisation code, can you move it to th
53 const v8::HandleScope handleScope; 59 const v8::HandleScope handleScope;
54 60
55 context = v8::Context::New(); 61 result->context = v8::Context::New();
56 AdblockPlus::GlobalJsObject::Setup(*this, appInfo, 62 AdblockPlus::GlobalJsObject::Setup(result, appInfo,
57 JsValuePtr(new JsValue(*this, context->Global()))); 63 JsValuePtr(new JsValue(result, result->context->Global())));
64 return result;
58 } 65 }
59 66
60 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::Evaluate(const std::string& sourc e, 67 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::Evaluate(const std::string& sourc e,
61 const std::string& filename) 68 const std::string& filename)
62 { 69 {
63 const Context context(*this); 70 const Context context(shared_from_this());
64 const v8::TryCatch tryCatch; 71 const v8::TryCatch tryCatch;
65 const v8::Handle<v8::Script> script = CompileScript(source, filename); 72 const v8::Handle<v8::Script> script = CompileScript(source, filename);
66 CheckTryCatch(tryCatch); 73 CheckTryCatch(tryCatch);
67 v8::Local<v8::Value> result = script->Run(); 74 v8::Local<v8::Value> result = script->Run();
68 CheckTryCatch(tryCatch); 75 CheckTryCatch(tryCatch);
69 return JsValuePtr(new JsValue(*this, result)); 76 return JsValuePtr(new JsValue(shared_from_this(), result));
70 } 77 }
71 78
72 void AdblockPlus::JsEngine::Load(const std::string& scriptPath) 79 void AdblockPlus::JsEngine::Load(const std::string& scriptPath)
73 { 80 {
74 const std::tr1::shared_ptr<std::istream> file = GetFileSystem()->Read(scriptPa th); 81 const std::tr1::shared_ptr<std::istream> file = GetFileSystem()->Read(scriptPa th);
75 if (!file || !*file) 82 if (!file || !*file)
76 throw std::runtime_error("Unable to load script " + scriptPath); 83 throw std::runtime_error("Unable to load script " + scriptPath);
77 Evaluate(Utils::Slurp(*file)); 84 Evaluate(Utils::Slurp(*file));
78 } 85 }
79 86
80 void AdblockPlus::JsEngine::Gc() 87 void AdblockPlus::JsEngine::Gc()
81 { 88 {
82 while (!v8::V8::IdleNotification()); 89 while (!v8::V8::IdleNotification());
83 } 90 }
84 91
85 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(const std::string& val) 92 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(const std::string& val)
86 { 93 {
87 const Context context(*this); 94 const Context context(shared_from_this());
88 return JsValuePtr(new JsValue(*this, v8::String::New(val.c_str(), val.length() ))); 95 return JsValuePtr(new JsValue(shared_from_this(),
96 v8::String::New(val.c_str(), val.length())));
89 } 97 }
90 98
91 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(int64_t val) 99 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(int64_t val)
92 { 100 {
93 const Context context(*this); 101 const Context context(shared_from_this());
94 return JsValuePtr(new JsValue(*this, v8::Integer::New(val))); 102 return JsValuePtr(new JsValue(shared_from_this(), v8::Integer::New(val)));
95 } 103 }
96 104
97 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(bool val) 105 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(bool val)
98 { 106 {
99 const Context context(*this); 107 const Context context(shared_from_this());
100 return JsValuePtr(new JsValue(*this, v8::Boolean::New(val))); 108 return JsValuePtr(new JsValue(shared_from_this(), v8::Boolean::New(val)));
101 } 109 }
102 110
103 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewObject() 111 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewObject()
104 { 112 {
105 const Context context(*this); 113 const Context context(shared_from_this());
106 return JsValuePtr(new JsValue(*this, v8::Object::New())); 114 return JsValuePtr(new JsValue(shared_from_this(), v8::Object::New()));
107 } 115 }
108 116
109 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewCallback( 117 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewCallback(
110 v8::InvocationCallback callback) 118 v8::InvocationCallback callback)
111 { 119 {
112 const Context context(*this); 120 const Context context(shared_from_this());
113 121
122 // Note: we are leaking this weak pointer, no obvious way to destroy it when
123 // it's no longer used
124 std::tr1::weak_ptr<JsEngine>* data =
125 new std::tr1::weak_ptr<JsEngine>(shared_from_this());
114 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback, 126 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback,
115 v8::External::New(this)); 127 v8::External::New(data));
116 return JsValuePtr(new JsValue(*this, templ->GetFunction())); 128 return JsValuePtr(new JsValue(shared_from_this(), templ->GetFunction()));
117 } 129 }
118 130
119 AdblockPlus::JsEngine& AdblockPlus::JsEngine::FromArguments(const v8::Arguments& arguments) 131 AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Argument s& arguments)
120 { 132 {
121 const v8::Local<const v8::External> external = 133 const v8::Local<const v8::External> external =
122 v8::Local<const v8::External>::Cast(arguments.Data()); 134 v8::Local<const v8::External>::Cast(arguments.Data());
123 return *static_cast<JsEngine* const>(external->Value()); 135 std::tr1::weak_ptr<JsEngine>* data =
136 static_cast<std::tr1::weak_ptr<JsEngine>*>(external->Value());
137 JsEnginePtr result = data->lock();
138 if (!result)
139 throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?") ;
140 return result;
124 } 141 }
125 142
126 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Argum ents& arguments) 143 AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Argum ents& arguments)
127 { 144 {
128 const Context context(*this); 145 const Context context(shared_from_this());
129 JsValueList list; 146 JsValueList list;
130 for (int i = 0; i < arguments.Length(); i++) 147 for (int i = 0; i < arguments.Length(); i++)
131 list.push_back(JsValuePtr(new JsValue(*this, arguments[i]))); 148 list.push_back(JsValuePtr(new JsValue(shared_from_this(), arguments[i])));
132 return list; 149 return list;
133 } 150 }
134 151
135 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem() 152 AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem()
136 { 153 {
137 if (!fileSystem) 154 if (!fileSystem)
138 fileSystem.reset(new DefaultFileSystem()); 155 fileSystem.reset(new DefaultFileSystem());
139 return fileSystem; 156 return fileSystem;
140 } 157 }
141 158
(...skipping 28 matching lines...) Expand all
170 } 187 }
171 188
172 void AdblockPlus::JsEngine::SetErrorCallback(AdblockPlus::ErrorCallbackPtr val) 189 void AdblockPlus::JsEngine::SetErrorCallback(AdblockPlus::ErrorCallbackPtr val)
173 { 190 {
174 if (!val) 191 if (!val)
175 throw std::runtime_error("ErrorCallback cannot be null"); 192 throw std::runtime_error("ErrorCallback cannot be null");
176 193
177 errorCallback = val; 194 errorCallback = val;
178 } 195 }
179 196
180 AdblockPlus::JsEngine::Context::Context(const JsEngine& jsEngine) 197 AdblockPlus::JsEngine::Context::Context(const JsEnginePtr jsEngine)
181 : locker(jsEngine.isolate), handleScope(), 198 : locker(jsEngine->isolate), handleScope(),
182 contextScope(jsEngine.context) 199 contextScope(jsEngine->context)
183 { 200 {
184 } 201 }
OLDNEW
« no previous file with comments | « src/GlobalJsObject.cpp ('k') | src/JsValue.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld