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-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 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 <cstdio> | 18 #include <cstdio> |
19 | 19 |
20 #include "generator.h" | 20 #include "generator.h" |
21 #include "library.h" | 21 #include "library.h" |
22 | 22 |
23 namespace | 23 namespace |
24 { | 24 { |
25 std::vector<bindings_internal::ClassInfo> classes; | 25 std::vector<bindings_internal::ClassInfo> classes; |
| 26 std::vector<bindings_internal::NamespaceInfo> namespaces; |
| 27 |
| 28 void printProperties(const bindings_internal::Properties& properties) |
| 29 { |
| 30 for (const auto& property : properties) |
| 31 { |
| 32 if (property.jsValue.empty()) |
| 33 { |
| 34 printf("get %s%s,\n", property.name.c_str(), |
| 35 wrapCall(property.getter, false).c_str()); |
| 36 if (!property.setter.empty()) |
| 37 { |
| 38 printf("set %s%s,\n", property.name.c_str(), |
| 39 wrapCall(property.setter, false).c_str()); |
| 40 } |
| 41 } |
| 42 else |
| 43 printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); |
| 44 } |
| 45 } |
| 46 |
| 47 void printMethods(const bindings_internal::Methods& methods, |
| 48 bool instanceOnly = true) |
| 49 { |
| 50 for (const auto& method : methods) |
| 51 if (!instanceOnly || method.call.instance_function) |
| 52 printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); |
| 53 } |
26 } | 54 } |
27 | 55 |
28 namespace bindings_internal | 56 namespace bindings_internal |
29 { | 57 { |
30 FunctionInfo::FunctionInfo() | 58 FunctionInfo::FunctionInfo() |
31 { | 59 { |
32 } | 60 } |
33 | 61 |
34 FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, | 62 FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, |
35 std::initializer_list<TypeCategory> argTypes, bool instance_function, | 63 std::initializer_list<TypeCategory> argTypes, bool instance_function, |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 211 |
184 if (classInfo->subclass_differentiator.offset != SIZE_MAX) | 212 if (classInfo->subclass_differentiator.offset != SIZE_MAX) |
185 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + classInfo->name); | 213 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + classInfo->name); |
186 | 214 |
187 DifferentiatorInfo differentiatorInfo; | 215 DifferentiatorInfo differentiatorInfo; |
188 differentiatorInfo.offset = offset; | 216 differentiatorInfo.offset = offset; |
189 differentiatorInfo.mapping = mapping; | 217 differentiatorInfo.mapping = mapping; |
190 classInfo->subclass_differentiator = differentiatorInfo; | 218 classInfo->subclass_differentiator = differentiatorInfo; |
191 } | 219 } |
192 | 220 |
| 221 NamespaceInfo* find_namespace(const char* namespaceName) |
| 222 { |
| 223 for (auto& namespaceInfo : namespaces) |
| 224 if (namespaceInfo.name == namespaceName) |
| 225 return &namespaceInfo; |
| 226 return nullptr; |
| 227 } |
| 228 |
| 229 void register_namespace(const char* name) |
| 230 { |
| 231 if (find_namespace(name)) |
| 232 throw std::runtime_error(std::string("Duplicate definition for namespace "
) + name); |
| 233 |
| 234 NamespaceInfo namespaceInfo; |
| 235 namespaceInfo.name = name; |
| 236 namespaces.push_back(namespaceInfo); |
| 237 } |
| 238 |
| 239 void register_namespace_property(const char* namespaceName, const char* name, |
| 240 const FunctionInfo& getter, const FunctionInfo& setter) |
| 241 { |
| 242 NamespaceInfo* namespaceInfo = find_namespace(namespaceName); |
| 243 if (!namespaceInfo) |
| 244 throw std::runtime_error(std::string("Property defined on unknown namespac
e: ") + name); |
| 245 |
| 246 PropertyInfo propertyInfo; |
| 247 propertyInfo.name = name; |
| 248 propertyInfo.getter = getter; |
| 249 propertyInfo.setter = setter; |
| 250 namespaceInfo->properties.push_back(propertyInfo); |
| 251 } |
| 252 |
| 253 void register_namespace_method(const char* namespaceName, const char* name, |
| 254 const FunctionInfo& call) |
| 255 { |
| 256 NamespaceInfo* namespaceInfo = find_namespace(namespaceName); |
| 257 if (!namespaceInfo) |
| 258 throw std::runtime_error(std::string("Method defined on unknown namespace:
") + name); |
| 259 |
| 260 MethodInfo methodInfo; |
| 261 methodInfo.name = name; |
| 262 methodInfo.call = call; |
| 263 namespaceInfo->methods.push_back(methodInfo); |
| 264 } |
| 265 |
193 std::string generateCall(const FunctionInfo& call, | 266 std::string generateCall(const FunctionInfo& call, |
194 std::vector<std::string>& params) | 267 std::vector<std::string>& params) |
195 { | 268 { |
196 if (call.returnType == TypeCategory::DEPENDENT_STRING || | 269 if (call.returnType == TypeCategory::DEPENDENT_STRING || |
197 call.returnType == TypeCategory::OWNED_STRING) | 270 call.returnType == TypeCategory::OWNED_STRING) |
198 { | 271 { |
199 params.insert(params.begin(), "string"); | 272 params.insert(params.begin(), "string"); |
200 } | 273 } |
201 | 274 |
202 std::string call_str(call.name); | 275 std::string call_str(call.name); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 if (i > 0) | 349 if (i > 0) |
277 prefix += ", "; | 350 prefix += ", "; |
278 prefix += argName; | 351 prefix += argName; |
279 | 352 |
280 if (call.args[i] == TypeCategory::STRING_REF) | 353 if (call.args[i] == TypeCategory::STRING_REF) |
281 { | 354 { |
282 hasStringArgs = true; | 355 hasStringArgs = true; |
283 params.push_back(std::string("createString(") + argName + ")"); | 356 params.push_back(std::string("createString(") + argName + ")"); |
284 } | 357 } |
285 else if (call.args[i] == TypeCategory::CLASS_PTR) | 358 else if (call.args[i] == TypeCategory::CLASS_PTR) |
286 params.push_back(argName + "._pointer"); | 359 params.push_back(argName + " ? " + argName + "._pointer : 0"); |
287 else if (call.args[i] == TypeCategory::INT64) | 360 else if (call.args[i] == TypeCategory::INT64) |
288 { | 361 { |
289 // 64-bit integers are passed as two integer parameters | 362 // 64-bit integers are passed as two integer parameters |
290 params.push_back(argName + " >>> 0"); | 363 params.push_back(argName + " >>> 0"); |
291 params.push_back(argName + " / 0x100000000 >>> 0"); | 364 params.push_back(argName + " / 0x100000000 >>> 0"); |
292 } | 365 } |
293 else | 366 else |
294 params.push_back(argName); | 367 params.push_back(argName); |
295 } | 368 } |
296 prefix += ")\n{\n"; | 369 prefix += ")\n{\n"; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 Module._ReleaseRef(this._pointer + ref_counted_offset); | 433 Module._ReleaseRef(this._pointer + ref_counted_offset); |
361 }; | 434 }; |
362 return result; | 435 return result; |
363 } | 436 } |
364 )"); | 437 )"); |
365 } | 438 } |
366 | 439 |
367 void printClass(const ClassInfo& cls) | 440 void printClass(const ClassInfo& cls) |
368 { | 441 { |
369 // Begin class definition | 442 // Begin class definition |
370 | |
371 ClassInfo* baseClass = find_class(cls.baseClass); | 443 ClassInfo* baseClass = find_class(cls.baseClass); |
372 printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 444 printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), |
373 (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 445 (baseClass ? ("exports." + baseClass->name).c_str() : "null"), |
374 cls.ref_counted_offset); | 446 cls.ref_counted_offset); |
375 | 447 |
376 // Print prototype members | 448 // Print prototype members |
377 | 449 printProperties(cls.properties); |
378 for (const auto& property : cls.properties) | 450 printMethods(cls.methods); |
379 { | |
380 if (property.jsValue.empty()) | |
381 { | |
382 printf("get %s%s,\n", property.name.c_str(), | |
383 wrapCall(property.getter, false).c_str()); | |
384 if (!property.setter.empty()) | |
385 { | |
386 printf("set %s%s,\n", property.name.c_str(), | |
387 wrapCall(property.setter, false).c_str()); | |
388 } | |
389 } | |
390 else | |
391 printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); | |
392 } | |
393 | |
394 for (const auto& method : cls.methods) | |
395 if (method.call.instance_function) | |
396 printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); | |
397 | 451 |
398 // End class definition | 452 // End class definition |
399 | |
400 printf("});\n"); | 453 printf("});\n"); |
401 | 454 |
402 // Print static members | 455 // Print static members |
403 | |
404 DifferentiatorInfo differentiator = cls.subclass_differentiator; | 456 DifferentiatorInfo differentiator = cls.subclass_differentiator; |
405 if (differentiator.offset != SIZE_MAX) | 457 if (differentiator.offset != SIZE_MAX) |
406 { | 458 { |
407 printf("var %s_mapping = \n", cls.name.c_str()); | 459 printf("var %s_mapping = \n", cls.name.c_str()); |
408 puts("{"); | 460 puts("{"); |
409 for (const auto& item : differentiator.mapping) | 461 for (const auto& item : differentiator.mapping) |
410 printf(" %i: '%s',\n", item.first, item.second.c_str()); | 462 printf(" %i: '%s',\n", item.first, item.second.c_str()); |
411 puts("};"); | 463 puts("};"); |
412 | 464 |
413 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 465 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); |
(...skipping 14 matching lines...) Expand all Loading... |
428 | 480 |
429 for (const auto& method : cls.methods) | 481 for (const auto& method : cls.methods) |
430 { | 482 { |
431 if (!method.call.instance_function) | 483 if (!method.call.instance_function) |
432 { | 484 { |
433 printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), | 485 printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), |
434 wrapCall(method.call).c_str()); | 486 wrapCall(method.call).c_str()); |
435 } | 487 } |
436 } | 488 } |
437 } | 489 } |
| 490 |
| 491 void printNamespace(const NamespaceInfo& namespaceInfo) |
| 492 { |
| 493 printf("exports.%s = {\n", namespaceInfo.name.c_str()); |
| 494 printProperties(namespaceInfo.properties); |
| 495 printMethods(namespaceInfo.methods, false); |
| 496 puts("};"); |
| 497 } |
438 } | 498 } |
439 | 499 |
440 void printBindings() | 500 void printBindings() |
441 { | 501 { |
442 bindings_internal::printHelpers(); | 502 bindings_internal::printHelpers(); |
443 | 503 |
444 for (const auto& item : classes) | 504 for (const auto& item : classes) |
445 bindings_internal::printClass(item); | 505 bindings_internal::printClass(item); |
| 506 for (const auto& item : namespaces) |
| 507 bindings_internal::printNamespace(item); |
446 } | 508 } |
OLD | NEW |