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-present eyeo GmbH | 3 * Copyright (C) 2006-present 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 <vector> | 18 #include <vector> |
19 #include <AdblockPlus.h> | 19 #include <AdblockPlus.h> |
20 | 20 |
21 #include "JsContext.h" | 21 #include "JsContext.h" |
22 #include "JsError.h" | 22 #include "JsError.h" |
23 #include "Utils.h" | 23 #include "Utils.h" |
24 | 24 |
25 using namespace AdblockPlus; | 25 using namespace AdblockPlus; |
26 | 26 |
27 AdblockPlus::JsValue::JsValue(AdblockPlus::JsEnginePtr jsEngine, | 27 template <> JSVALUEV8::JsValueTemplate(AdblockPlus::JsEnginePtr jsEngine, |
28 v8::Handle<v8::Value> value) | 28 v8::Handle<v8::Value> value) |
29 : jsEngine(jsEngine), | 29 : jsEngine(jsEngine), |
30 value(new v8::Global<v8::Value>(jsEngine->GetIsolate(), value)) | 30 value(new v8::Global<v8::Value>(jsEngine->GetIsolate(), value)) |
31 { | 31 { |
32 } | 32 } |
33 | 33 |
34 AdblockPlus::JsValue::JsValue(AdblockPlus::JsValue&& src) | 34 template <> JSVALUEV8::JsValueTemplate(JSVALUEV8&& src) |
35 : jsEngine(src.jsEngine), | 35 : jsEngine(src.jsEngine), |
36 value(std::move(src.value)) | 36 value(std::move(src.value)) |
37 { | 37 { |
38 } | 38 } |
39 | 39 |
40 AdblockPlus::JsValue::JsValue(const JsValue& src) | 40 template <> JSVALUEV8::JsValueTemplate(const JSVALUEV8& src) |
41 : jsEngine(src.jsEngine) | 41 : jsEngine(src.jsEngine) |
42 { | 42 { |
43 const JsContext context(*src.jsEngine); | 43 const JsContext context(*src.jsEngine); |
44 value.reset(new v8::Global<v8::Value>(src.jsEngine->GetIsolate(), *src.value))
; | 44 value.reset(new v8::Global<v8::Value>(src.jsEngine->GetIsolate(), *src.value))
; |
45 } | 45 } |
46 | 46 |
47 AdblockPlus::JsValue::~JsValue() | 47 template <> JSVALUEV8::~JsValueTemplate() |
48 { | 48 { |
49 if (value) | 49 if (value) |
50 { | 50 { |
51 const JsContext context(*jsEngine); | 51 const JsContext context(*jsEngine); |
52 value.reset(); | 52 value.reset(); |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 JsValue& AdblockPlus::JsValue::operator=(const JsValue& src) | 56 template <> JSVALUEV8& JSVALUEV8::operator=(const JSVALUEV8& src) |
57 { | 57 { |
58 const JsContext context(*src.jsEngine); | 58 const JsContext context(*src.jsEngine); |
59 jsEngine = src.jsEngine; | 59 jsEngine = src.jsEngine; |
60 value.reset(new v8::Global<v8::Value>(src.jsEngine->GetIsolate(), *src.value))
; | 60 value.reset(new v8::Global<v8::Value>(src.jsEngine->GetIsolate(), *src.value))
; |
61 | 61 |
62 return *this; | 62 return *this; |
63 } | 63 } |
64 | 64 |
65 JsValue& AdblockPlus::JsValue::operator=(JsValue&& src) | 65 template <> JSVALUEV8& AdblockPlus::JSVALUEV8::operator=(JSVALUEV8&& src) |
66 { | 66 { |
67 jsEngine = std::move(src.jsEngine); | 67 jsEngine = std::move(src.jsEngine); |
68 value = std::move(src.value); | 68 value = std::move(src.value); |
69 | 69 |
70 return *this; | 70 return *this; |
71 } | 71 } |
72 | 72 |
73 bool AdblockPlus::JsValue::IsUndefined() const | 73 template <> bool AdblockPlus::JSVALUEV8::IsUndefined() const |
74 { | 74 { |
75 const JsContext context(*jsEngine); | 75 const JsContext context(*jsEngine); |
76 return UnwrapValue()->IsUndefined(); | 76 return UnwrapValue()->IsUndefined(); |
77 } | 77 } |
78 | 78 |
79 bool AdblockPlus::JsValue::IsNull() const | 79 template <> bool AdblockPlus::JSVALUEV8::IsNull() const |
80 { | 80 { |
81 const JsContext context(*jsEngine); | 81 const JsContext context(*jsEngine); |
82 return UnwrapValue()->IsNull(); | 82 return UnwrapValue()->IsNull(); |
83 } | 83 } |
84 | 84 |
85 bool AdblockPlus::JsValue::IsString() const | 85 template <> bool AdblockPlus::JSVALUEV8::IsString() const |
86 { | 86 { |
87 const JsContext context(*jsEngine); | 87 const JsContext context(*jsEngine); |
88 v8::Local<v8::Value> value = UnwrapValue(); | 88 v8::Local<v8::Value> value = UnwrapValue(); |
89 return value->IsString() || value->IsStringObject(); | 89 return value->IsString() || value->IsStringObject(); |
90 } | 90 } |
91 | 91 |
92 bool AdblockPlus::JsValue::IsNumber() const | 92 template <> bool AdblockPlus::JSVALUEV8::IsNumber() const |
93 { | 93 { |
94 const JsContext context(*jsEngine); | 94 const JsContext context(*jsEngine); |
95 v8::Local<v8::Value> value = UnwrapValue(); | 95 v8::Local<v8::Value> value = UnwrapValue(); |
96 return value->IsNumber() || value->IsNumberObject(); | 96 return value->IsNumber() || value->IsNumberObject(); |
97 } | 97 } |
98 | 98 |
99 bool AdblockPlus::JsValue::IsBool() const | 99 template <> bool AdblockPlus::JSVALUEV8::IsBool() const |
100 { | 100 { |
101 const JsContext context(*jsEngine); | 101 const JsContext context(*jsEngine); |
102 v8::Local<v8::Value> value = UnwrapValue(); | 102 v8::Local<v8::Value> value = UnwrapValue(); |
103 return value->IsBoolean() || value->IsBooleanObject(); | 103 return value->IsBoolean() || value->IsBooleanObject(); |
104 } | 104 } |
105 | 105 |
106 bool AdblockPlus::JsValue::IsObject() const | 106 template <> bool AdblockPlus::JSVALUEV8::IsObject() const |
107 { | 107 { |
108 const JsContext context(*jsEngine); | 108 const JsContext context(*jsEngine); |
109 return UnwrapValue()->IsObject(); | 109 return UnwrapValue()->IsObject(); |
110 } | 110 } |
111 | 111 |
112 bool AdblockPlus::JsValue::IsArray() const | 112 template <> bool AdblockPlus::JSVALUEV8::IsArray() const |
113 { | 113 { |
114 const JsContext context(*jsEngine); | 114 const JsContext context(*jsEngine); |
115 return UnwrapValue()->IsArray(); | 115 return UnwrapValue()->IsArray(); |
116 } | 116 } |
117 | 117 |
118 bool AdblockPlus::JsValue::IsFunction() const | 118 template <> bool AdblockPlus::JSVALUEV8::IsFunction() const |
119 { | 119 { |
120 const JsContext context(*jsEngine); | 120 const JsContext context(*jsEngine); |
121 return UnwrapValue()->IsFunction(); | 121 return UnwrapValue()->IsFunction(); |
122 } | 122 } |
123 | 123 |
124 std::string AdblockPlus::JsValue::AsString() const | 124 template <> std::string AdblockPlus::JSVALUEV8::AsString() const |
125 { | 125 { |
126 const JsContext context(*jsEngine); | 126 const JsContext context(*jsEngine); |
127 return Utils::FromV8String(UnwrapValue()); | 127 return Utils::FromV8String(UnwrapValue()); |
128 } | 128 } |
129 | 129 |
130 StringBuffer AdblockPlus::JsValue::AsStringBuffer() const | 130 template <> StringBuffer AdblockPlus::JSVALUEV8::AsStringBuffer() const |
131 { | 131 { |
132 const JsContext context(*jsEngine); | 132 const JsContext context(*jsEngine); |
133 return Utils::StringBufferFromV8String(UnwrapValue()); | 133 return Utils::StringBufferFromV8String(UnwrapValue()); |
134 } | 134 } |
135 | 135 |
136 int64_t AdblockPlus::JsValue::AsInt() const | 136 template <> int64_t AdblockPlus::JSVALUEV8::AsInt() const |
137 { | 137 { |
138 const JsContext context(*jsEngine); | 138 const JsContext context(*jsEngine); |
139 return UnwrapValue()->IntegerValue(); | 139 return UnwrapValue()->IntegerValue(); |
140 } | 140 } |
141 | 141 |
142 bool AdblockPlus::JsValue::AsBool() const | 142 template <> bool AdblockPlus::JSVALUEV8::AsBool() const |
143 { | 143 { |
144 const JsContext context(*jsEngine); | 144 const JsContext context(*jsEngine); |
145 return UnwrapValue()->BooleanValue(); | 145 return UnwrapValue()->BooleanValue(); |
146 } | 146 } |
147 | 147 |
148 AdblockPlus::JsValueList AdblockPlus::JsValue::AsList() const | 148 template <> AdblockPlus::JsValueList AdblockPlus::JSVALUEV8::AsList() const |
149 { | 149 { |
150 if (!IsArray()) | 150 if (!IsArray()) |
151 throw std::runtime_error("Cannot convert a non-array to list"); | 151 throw std::runtime_error("Cannot convert a non-array to list"); |
152 | 152 |
153 const JsContext context(*jsEngine); | 153 const JsContext context(*jsEngine); |
154 JsValueList result; | 154 JsValueList result; |
155 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(UnwrapValue()); | 155 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(UnwrapValue()); |
156 uint32_t length = array->Length(); | 156 uint32_t length = array->Length(); |
157 for (uint32_t i = 0; i < length; i++) | 157 for (uint32_t i = 0; i < length; i++) |
158 { | 158 { |
159 v8::Local<v8::Value> item = array->Get(i); | 159 v8::Local<v8::Value> item = array->Get(i); |
160 result.push_back(JsValue(jsEngine, item)); | 160 result.push_back(JsValue(jsEngine, item)); |
161 } | 161 } |
162 return result; | 162 return result; |
163 } | 163 } |
164 | 164 |
165 std::vector<std::string> AdblockPlus::JsValue::GetOwnPropertyNames() const | 165 template <> std::vector<std::string> AdblockPlus::JSVALUEV8::GetOwnPropertyNames
() const |
166 { | 166 { |
167 if (!IsObject()) | 167 if (!IsObject()) |
168 throw std::runtime_error("Attempting to get propert list for a non-object"); | 168 throw std::runtime_error("Attempting to get propert list for a non-object"); |
169 | 169 |
170 const JsContext context(*jsEngine); | 170 const JsContext context(*jsEngine); |
171 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(UnwrapValue()); | 171 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(UnwrapValue()); |
172 JsValueList properties = JsValue(jsEngine, object->GetOwnPropertyNames()).AsLi
st(); | 172 JsValueList properties = JsValue(jsEngine, object->GetOwnPropertyNames()).AsLi
st(); |
173 std::vector<std::string> result; | 173 std::vector<std::string> result; |
174 for (const auto& property : properties) | 174 for (const auto& property : properties) |
175 result.push_back(property.AsString()); | 175 result.push_back(property.AsString()); |
176 return result; | 176 return result; |
177 } | 177 } |
178 | 178 |
179 | 179 |
180 AdblockPlus::JsValue AdblockPlus::JsValue::GetProperty(const std::string& name)
const | 180 template <> AdblockPlus::JsValue AdblockPlus::JSVALUEV8::GetProperty(const std::
string& name) const |
181 { | 181 { |
182 if (!IsObject()) | 182 if (!IsObject()) |
183 throw std::runtime_error("Attempting to get property of a non-object"); | 183 throw std::runtime_error("Attempting to get property of a non-object"); |
184 | 184 |
185 const JsContext context(*jsEngine); | 185 const JsContext context(*jsEngine); |
186 v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), nam
e); | 186 v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), nam
e); |
187 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); | 187 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
188 return JsValue(jsEngine, obj->Get(property)); | 188 return JsValue(jsEngine, obj->Get(property)); |
189 } | 189 } |
190 | 190 |
191 void AdblockPlus::JsValue::SetProperty(const std::string& name, v8::Handle<v8::V
alue> val) | 191 template <> void AdblockPlus::JSVALUEV8::SetProperty(const std::string& name, v8
::Handle<v8::Value> val) |
192 { | 192 { |
193 if (!IsObject()) | 193 if (!IsObject()) |
194 throw std::runtime_error("Attempting to set property on a non-object"); | 194 throw std::runtime_error("Attempting to set property on a non-object"); |
195 | 195 |
196 v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), nam
e); | 196 v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), nam
e); |
197 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); | 197 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
198 obj->Set(property, val); | 198 obj->Set(property, val); |
199 } | 199 } |
200 | 200 |
201 v8::Local<v8::Value> AdblockPlus::JsValue::UnwrapValue() const | 201 template <> JsEngineNamespaceImpl::LocalValue AdblockPlus::JSVALUEV8::UnwrapValu
e() const |
202 { | 202 { |
203 return v8::Local<v8::Value>::New(jsEngine->GetIsolate(), *value); | 203 return v8::Local<v8::Value>::New(jsEngine->GetIsolate(), *value); |
204 } | 204 } |
205 | 205 |
206 void AdblockPlus::JsValue::SetProperty(const std::string& name, const std::strin
g& val) | 206 template <> void AdblockPlus::JSVALUEV8::SetProperty(const std::string& name, co
nst std::string& val) |
207 { | 207 { |
208 const JsContext context(*jsEngine); | 208 const JsContext context(*jsEngine); |
209 SetProperty(name, Utils::ToV8String(jsEngine->GetIsolate(), val)); | 209 SetProperty(name, Utils::ToV8String(jsEngine->GetIsolate(), val)); |
210 } | 210 } |
211 | 211 |
212 void AdblockPlus::JsValue::SetStringBufferProperty(const std::string& name, cons
t StringBuffer& val) | 212 template <> void AdblockPlus::JSVALUEV8::SetStringBufferProperty(const std::stri
ng& name, const StringBuffer& val) |
213 { | 213 { |
214 const JsContext context(*jsEngine); | 214 const JsContext context(*jsEngine); |
215 SetProperty(name, Utils::StringBufferToV8String(jsEngine->GetIsolate(), val)); | 215 SetProperty(name, Utils::StringBufferToV8String(jsEngine->GetIsolate(), val)); |
216 } | 216 } |
217 | 217 |
218 void AdblockPlus::JsValue::SetProperty(const std::string& name, int64_t val) | 218 template <> void AdblockPlus::JSVALUEV8::SetProperty(const std::string& name, in
t64_t val) |
219 { | 219 { |
220 const JsContext context(*jsEngine); | 220 const JsContext context(*jsEngine); |
221 SetProperty(name, v8::Number::New(jsEngine->GetIsolate(), val)); | 221 SetProperty(name, v8::Number::New(jsEngine->GetIsolate(), val)); |
222 } | 222 } |
223 | 223 |
224 void AdblockPlus::JsValue::SetProperty(const std::string& name, const JsValue& v
al) | 224 template <> void AdblockPlus::JSVALUEV8::SetProperty(const std::string& name, co
nst JsValue& val) |
225 { | 225 { |
226 const JsContext context(*jsEngine); | 226 const JsContext context(*jsEngine); |
227 SetProperty(name, val.UnwrapValue()); | 227 SetProperty(name, val.UnwrapValue()); |
228 } | 228 } |
229 | 229 |
230 void AdblockPlus::JsValue::SetProperty(const std::string& name, bool val) | 230 template <> void AdblockPlus::JSVALUEV8::SetProperty(const std::string& name, bo
ol val) |
231 { | 231 { |
232 const JsContext context(*jsEngine); | 232 const JsContext context(*jsEngine); |
233 SetProperty(name, v8::Boolean::New(jsEngine->GetIsolate(), val)); | 233 SetProperty(name, v8::Boolean::New(jsEngine->GetIsolate(), val)); |
234 } | 234 } |
235 | 235 |
236 std::string AdblockPlus::JsValue::GetClass() const | 236 template <> std::string AdblockPlus::JSVALUEV8::GetClass() const |
237 { | 237 { |
238 if (!IsObject()) | 238 if (!IsObject()) |
239 throw std::runtime_error("Cannot get constructor of a non-object"); | 239 throw std::runtime_error("Cannot get constructor of a non-object"); |
240 | 240 |
241 const JsContext context(*jsEngine); | 241 const JsContext context(*jsEngine); |
242 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); | 242 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue()); |
243 return Utils::FromV8String(obj->GetConstructorName()); | 243 return Utils::FromV8String(obj->GetConstructorName()); |
244 } | 244 } |
245 | 245 |
246 JsValue JsValue::Call(const JsValueList& params) const | 246 template <> JsValue JSVALUEV8::Call(const JsValueList& params) const |
247 { | 247 { |
248 const JsContext context(*jsEngine); | 248 const JsContext context(*jsEngine); |
249 std::vector<v8::Handle<v8::Value>> argv; | 249 std::vector<v8::Handle<v8::Value>> argv; |
250 for (const auto& param : params) | 250 for (const auto& param : params) |
251 argv.push_back(param.UnwrapValue()); | 251 argv.push_back(param.UnwrapValue()); |
252 | 252 |
253 return Call(argv, context.GetV8Context()->Global()); | 253 return Call(argv, context.GetJSEngineContext()->Global()); |
254 } | 254 } |
255 | 255 |
256 JsValue JsValue::Call(const JsValueList& params, const JsValue& thisValue) const | 256 template <> JsValue JSVALUEV8::Call(const JsValueList& params, const JsValue& th
isValue) const |
257 { | 257 { |
258 const JsContext context(*jsEngine); | 258 const JsContext context(*jsEngine); |
259 v8::Local<v8::Object> thisObj = v8::Local<v8::Object>::Cast(thisValue.UnwrapVa
lue()); | 259 v8::Local<v8::Object> thisObj = v8::Local<v8::Object>::Cast(thisValue.UnwrapVa
lue()); |
260 | 260 |
261 std::vector<v8::Handle<v8::Value>> argv; | 261 std::vector<v8::Handle<v8::Value>> argv; |
262 for (const auto& param : params) | 262 for (const auto& param : params) |
263 argv.push_back(param.UnwrapValue()); | 263 argv.push_back(param.UnwrapValue()); |
264 | 264 |
265 return Call(argv, thisObj); | 265 return Call(argv, thisObj); |
266 } | 266 } |
267 | 267 |
268 JsValue JsValue::Call(const JsValue& arg) const | 268 template <> JsValue JSVALUEV8::Call(const JsValue& arg) const |
269 { | 269 { |
270 const JsContext context(*jsEngine); | 270 const JsContext context(*jsEngine); |
271 | 271 |
272 std::vector<v8::Handle<v8::Value>> argv; | 272 std::vector<v8::Handle<v8::Value>> argv; |
273 argv.push_back(arg.UnwrapValue()); | 273 argv.push_back(arg.UnwrapValue()); |
274 | 274 |
275 return Call(argv, context.GetV8Context()->Global()); | 275 return Call(argv, context.GetJSEngineContext()->Global()); |
276 } | 276 } |
277 | 277 |
278 JsValue JsValue::Call(std::vector<v8::Handle<v8::Value>>& args, v8::Local<v8::Ob
ject> thisObj) const | 278 template <> JsValue JSVALUEV8::Call(std::vector<v8::Handle<v8::Value>>& args, v8
::Local<v8::Object> thisObj) const |
279 { | 279 { |
280 if (!IsFunction()) | 280 if (!IsFunction()) |
281 throw std::runtime_error("Attempting to call a non-function"); | 281 throw std::runtime_error("Attempting to call a non-function"); |
282 if (!thisObj->IsObject()) | 282 if (!thisObj->IsObject()) |
283 throw std::runtime_error("`this` pointer has to be an object"); | 283 throw std::runtime_error("`this` pointer has to be an object"); |
284 | 284 |
285 const JsContext context(*jsEngine); | 285 const JsContext context(*jsEngine); |
286 | 286 |
287 const v8::TryCatch tryCatch; | 287 const v8::TryCatch tryCatch; |
288 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(UnwrapValue()); | 288 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(UnwrapValue()); |
289 v8::Local<v8::Value> result = func->Call(thisObj, args.size(), | 289 v8::Local<v8::Value> result = func->Call(thisObj, args.size(), |
290 args.size() ? &args[0] : nullptr); | 290 args.size() ? &args[0] : nullptr); |
291 | 291 |
292 if (tryCatch.HasCaught()) | 292 if (tryCatch.HasCaught()) |
293 throw JsError(tryCatch.Exception(), tryCatch.Message()); | 293 throw JsError(tryCatch.Exception(), tryCatch.Message()); |
294 | 294 |
295 return JsValue(jsEngine, result); | 295 return JsValue(jsEngine, result); |
296 } | 296 } |
OLD | NEW |