| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 282       if (i > 0) | 355       if (i > 0) | 
| 283         prefix += ", "; | 356         prefix += ", "; | 
| 284       prefix += argName; | 357       prefix += argName; | 
| 285 | 358 | 
| 286       if (call.args[i] == TypeCategory::STRING_REF) | 359       if (call.args[i] == TypeCategory::STRING_REF) | 
| 287       { | 360       { | 
| 288         hasStringArgs = true; | 361         hasStringArgs = true; | 
| 289         params.push_back(std::string("createString(") + argName + ")"); | 362         params.push_back(std::string("createString(") + argName + ")"); | 
| 290       } | 363       } | 
| 291       else if (call.args[i] == TypeCategory::CLASS_PTR) | 364       else if (call.args[i] == TypeCategory::CLASS_PTR) | 
| 292         params.push_back(argName + "._pointer"); | 365         params.push_back(argName + " ? " + argName + "._pointer : 0"); | 
| 293       else if (call.args[i] == TypeCategory::INT64) | 366       else if (call.args[i] == TypeCategory::INT64) | 
| 294       { | 367       { | 
| 295         // 64-bit integers are passed as two integer parameters | 368         // 64-bit integers are passed as two integer parameters | 
| 296         params.push_back(argName + " >>> 0"); | 369         params.push_back(argName + " >>> 0"); | 
| 297         params.push_back(argName + " / 0x100000000 >>> 0"); | 370         params.push_back(argName + " / 0x100000000 >>> 0"); | 
| 298       } | 371       } | 
| 299       else | 372       else | 
| 300         params.push_back(argName); | 373         params.push_back(argName); | 
| 301     } | 374     } | 
| 302     prefix += ")\n{\n"; | 375     prefix += ")\n{\n"; | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 373           Module._ReleaseRef(this._pointer + ref_counted_offset); | 446           Module._ReleaseRef(this._pointer + ref_counted_offset); | 
| 374         }; | 447         }; | 
| 375         return result; | 448         return result; | 
| 376       } | 449       } | 
| 377     )"); | 450     )"); | 
| 378   } | 451   } | 
| 379 | 452 | 
| 380   void printClass(const ClassInfo& cls) | 453   void printClass(const ClassInfo& cls) | 
| 381   { | 454   { | 
| 382     // Begin class definition | 455     // Begin class definition | 
| 383 |  | 
| 384     ClassInfo* baseClass = find_class(cls.baseClass); | 456     ClassInfo* baseClass = find_class(cls.baseClass); | 
| 385     printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 457     printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 
| 386         (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 458         (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 
| 387         cls.ref_counted_offset); | 459         cls.ref_counted_offset); | 
| 388 | 460 | 
| 389     // Print prototype members | 461     // Print prototype members | 
| 390 | 462     printProperties(cls.properties); | 
| 391     for (const auto& property : cls.properties) | 463     printMethods(cls.methods); | 
| 392     { |  | 
| 393       if (property.jsValue.empty()) |  | 
| 394       { |  | 
| 395         printf("get %s%s,\n", property.name.c_str(), |  | 
| 396                wrapCall(property.getter, false).c_str()); |  | 
| 397         if (!property.setter.empty()) |  | 
| 398         { |  | 
| 399           printf("set %s%s,\n", property.name.c_str(), |  | 
| 400                  wrapCall(property.setter, false).c_str()); |  | 
| 401         } |  | 
| 402       } |  | 
| 403       else |  | 
| 404         printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); |  | 
| 405     } |  | 
| 406 |  | 
| 407     for (const auto& method : cls.methods) |  | 
| 408       if (method.call.instance_function) |  | 
| 409         printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); |  | 
| 410 | 464 | 
| 411     // End class definition | 465     // End class definition | 
| 412 |  | 
| 413     printf("});\n"); | 466     printf("});\n"); | 
| 414 | 467 | 
| 415     // Print static members | 468     // Print static members | 
| 416 |  | 
| 417     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 469     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 
| 418     if (differentiator.offset != SIZE_MAX) | 470     if (differentiator.offset != SIZE_MAX) | 
| 419     { | 471     { | 
| 420       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 472       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 
| 421       puts("{"); | 473       puts("{"); | 
| 422       printf("  var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); | 474       printf("  var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); | 
| 423       printf("  if (type in %s_mapping)\n", cls.name.c_str()); | 475       printf("  if (type in %s_mapping)\n", cls.name.c_str()); | 
| 424       printf("    return new %s_mapping[type](ptr);\n", cls.name.c_str()); | 476       printf("    return new %s_mapping[type](ptr);\n", cls.name.c_str()); | 
| 425       printf("  throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
     tr()); | 477       printf("  throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
     tr()); | 
| 426       puts("};"); | 478       puts("};"); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 448       DifferentiatorInfo differentiator = cls.subclass_differentiator; | 500       DifferentiatorInfo differentiator = cls.subclass_differentiator; | 
| 449       if (differentiator.offset == SIZE_MAX) | 501       if (differentiator.offset == SIZE_MAX) | 
| 450         return; | 502         return; | 
| 451 | 503 | 
| 452       printf("var %s_mapping = \n", cls.name.c_str()); | 504       printf("var %s_mapping = \n", cls.name.c_str()); | 
| 453       puts("{"); | 505       puts("{"); | 
| 454       for (const auto& item : differentiator.mapping) | 506       for (const auto& item : differentiator.mapping) | 
| 455         printf("  %i: exports.%s,\n", item.first, item.second.c_str()); | 507         printf("  %i: exports.%s,\n", item.first, item.second.c_str()); | 
| 456       puts("};"); | 508       puts("};"); | 
| 457   } | 509   } | 
|  | 510 | 
|  | 511   void printNamespace(const NamespaceInfo& namespaceInfo) | 
|  | 512   { | 
|  | 513     printf("exports.%s = {\n", namespaceInfo.name.c_str()); | 
|  | 514     printProperties(namespaceInfo.properties); | 
|  | 515     printMethods(namespaceInfo.methods, false); | 
|  | 516     puts("};"); | 
|  | 517   } | 
| 458 } | 518 } | 
| 459 | 519 | 
| 460 void printBindings() | 520 void printBindings() | 
| 461 { | 521 { | 
| 462   bindings_internal::printHelpers(); | 522   bindings_internal::printHelpers(); | 
| 463 | 523 | 
| 464   for (const auto& cls : classes) | 524   for (const auto& cls : classes) | 
| 465     bindings_internal::printClass(cls); | 525     bindings_internal::printClass(cls); | 
| 466   for (const auto& cls : classes) | 526   for (const auto& cls : classes) | 
| 467     bindings_internal::printClassMapping(cls); | 527     bindings_internal::printClassMapping(cls); | 
|  | 528   for (const auto& namespace_ : namespaces) | 
|  | 529     bindings_internal::printNamespace(namespace_); | 
| 468 } | 530 } | 
| OLD | NEW | 
|---|