| 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 <emscripten.h> | 20 #include <emscripten.h> | 
| 21 | 21 | 
| 22 #include "generator.h" | 22 #include "generator.h" | 
| 23 | 23 | 
| 24 namespace | 24 namespace | 
| 25 { | 25 { | 
| 26   std::vector<bindings_internal::ClassInfo> classes; | 26   std::vector<bindings_internal::ClassInfo> classes; | 
|  | 27   std::vector<bindings_internal::NamespaceInfo> namespaces; | 
|  | 28 | 
|  | 29   void printProperties(const bindings_internal::PropertyList& properties) | 
|  | 30   { | 
|  | 31     for (const auto& property : properties) | 
|  | 32     { | 
|  | 33       if (property.jsValue.empty()) | 
|  | 34       { | 
|  | 35         printf("get %s%s,\n", property.name.c_str(), | 
|  | 36                wrapCall(property.getter, false).c_str()); | 
|  | 37         if (!property.setter.empty()) | 
|  | 38         { | 
|  | 39           printf("set %s%s,\n", property.name.c_str(), | 
|  | 40                  wrapCall(property.setter, false).c_str()); | 
|  | 41         } | 
|  | 42       } | 
|  | 43       else | 
|  | 44         printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); | 
|  | 45     } | 
|  | 46   } | 
|  | 47 | 
|  | 48   void printMethods(const bindings_internal::MethodList& methods, | 
|  | 49                     bool instanceOnly = true) | 
|  | 50   { | 
|  | 51     for (const auto& method : methods) | 
|  | 52       if (!instanceOnly || method.call.instance_function) | 
|  | 53         printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); | 
|  | 54   } | 
| 27 } | 55 } | 
| 28 | 56 | 
| 29 namespace bindings_internal | 57 namespace bindings_internal | 
| 30 { | 58 { | 
| 31   FunctionInfo::FunctionInfo() | 59   FunctionInfo::FunctionInfo() | 
| 32   { | 60   { | 
| 33     name[0] = '\0'; | 61     name[0] = '\0'; | 
| 34   } | 62   } | 
| 35 | 63 | 
| 36   FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, | 64   FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, | 
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 248 | 276 | 
| 249     if (classInfo->subclass_differentiator.offset != SIZE_MAX) | 277     if (classInfo->subclass_differentiator.offset != SIZE_MAX) | 
| 250       throw std::runtime_error("More than one subclass differentiator defined fo
     r class " + classInfo->name); | 278       throw std::runtime_error("More than one subclass differentiator defined fo
     r class " + classInfo->name); | 
| 251 | 279 | 
| 252     DifferentiatorInfo differentiatorInfo; | 280     DifferentiatorInfo differentiatorInfo; | 
| 253     differentiatorInfo.offset = offset; | 281     differentiatorInfo.offset = offset; | 
| 254     differentiatorInfo.mapping = mapping; | 282     differentiatorInfo.mapping = mapping; | 
| 255     classInfo->subclass_differentiator = differentiatorInfo; | 283     classInfo->subclass_differentiator = differentiatorInfo; | 
| 256   } | 284   } | 
| 257 | 285 | 
|  | 286   NamespaceInfo* find_namespace(const char* namespaceName) | 
|  | 287   { | 
|  | 288     for (auto& namespaceInfo : namespaces) | 
|  | 289       if (namespaceInfo.name == namespaceName) | 
|  | 290         return &namespaceInfo; | 
|  | 291     return nullptr; | 
|  | 292   } | 
|  | 293 | 
|  | 294   void register_namespace(const char* name) | 
|  | 295   { | 
|  | 296     if (find_namespace(name)) | 
|  | 297       throw std::runtime_error(std::string("Duplicate definition for namespace "
     ) + name); | 
|  | 298 | 
|  | 299     NamespaceInfo namespaceInfo; | 
|  | 300     namespaceInfo.name = name; | 
|  | 301     namespaces.push_back(namespaceInfo); | 
|  | 302   } | 
|  | 303 | 
|  | 304   void register_namespace_property(const char* namespaceName, const char* name, | 
|  | 305       const FunctionInfo& getter, const FunctionInfo& setter) | 
|  | 306   { | 
|  | 307     NamespaceInfo* namespaceInfo = find_namespace(namespaceName); | 
|  | 308     if (!namespaceInfo) | 
|  | 309       throw std::runtime_error(std::string("Property defined on unknown namespac
     e: ") + name); | 
|  | 310 | 
|  | 311     PropertyInfo propertyInfo; | 
|  | 312     propertyInfo.name = name; | 
|  | 313     propertyInfo.getter = getter; | 
|  | 314     propertyInfo.setter = setter; | 
|  | 315     namespaceInfo->properties.push_back(propertyInfo); | 
|  | 316   } | 
|  | 317 | 
|  | 318   void register_namespace_method(const char* namespaceName, const char* name, | 
|  | 319       const FunctionInfo& call) | 
|  | 320   { | 
|  | 321     NamespaceInfo* namespaceInfo = find_namespace(namespaceName); | 
|  | 322     if (!namespaceInfo) | 
|  | 323       throw std::runtime_error(std::string("Method defined on unknown namespace:
      ") + name); | 
|  | 324 | 
|  | 325     MethodInfo methodInfo; | 
|  | 326     methodInfo.name = name; | 
|  | 327     methodInfo.call = call; | 
|  | 328     namespaceInfo->methods.push_back(methodInfo); | 
|  | 329   } | 
|  | 330 | 
| 258   std::string generateCall(const FunctionInfo& call, | 331   std::string generateCall(const FunctionInfo& call, | 
| 259       std::vector<std::string>& params) | 332       std::vector<std::string>& params) | 
| 260   { | 333   { | 
| 261     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 334     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 
| 262         call.returnType == TypeCategory::OWNED_STRING) | 335         call.returnType == TypeCategory::OWNED_STRING) | 
| 263     { | 336     { | 
| 264       params.insert(params.begin(), "string"); | 337       params.insert(params.begin(), "string"); | 
| 265     } | 338     } | 
| 266 | 339 | 
| 267     std::string call_str(call.name); | 340     std::string call_str(call.name); | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 341       if (i > 0) | 414       if (i > 0) | 
| 342         prefix += ", "; | 415         prefix += ", "; | 
| 343       prefix += argName; | 416       prefix += argName; | 
| 344 | 417 | 
| 345       if (call.args[i] == TypeCategory::STRING_REF) | 418       if (call.args[i] == TypeCategory::STRING_REF) | 
| 346       { | 419       { | 
| 347         hasStringArgs = true; | 420         hasStringArgs = true; | 
| 348         params.push_back(std::string("createString(") + argName + ")"); | 421         params.push_back(std::string("createString(") + argName + ")"); | 
| 349       } | 422       } | 
| 350       else if (call.args[i] == TypeCategory::CLASS_PTR) | 423       else if (call.args[i] == TypeCategory::CLASS_PTR) | 
| 351         params.push_back(argName + "._pointer"); | 424         params.push_back(argName + " ? " + argName + "._pointer : 0"); | 
| 352       else if (call.args[i] == TypeCategory::INT64) | 425       else if (call.args[i] == TypeCategory::INT64) | 
| 353       { | 426       { | 
| 354         // 64-bit integers are passed as two integer parameters | 427         // 64-bit integers are passed as two integer parameters | 
| 355         params.push_back(argName + " >>> 0"); | 428         params.push_back(argName + " >>> 0"); | 
| 356         params.push_back(argName + " / 0x100000000 >>> 0"); | 429         params.push_back(argName + " / 0x100000000 >>> 0"); | 
| 357       } | 430       } | 
| 358       else | 431       else | 
| 359         params.push_back(argName); | 432         params.push_back(argName); | 
| 360     } | 433     } | 
| 361     prefix += ")\n{\n"; | 434     prefix += ")\n{\n"; | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 425           Module._ReleaseRef(this._pointer + ref_counted_offset); | 498           Module._ReleaseRef(this._pointer + ref_counted_offset); | 
| 426         }; | 499         }; | 
| 427         return result; | 500         return result; | 
| 428       } | 501       } | 
| 429     )"); | 502     )"); | 
| 430   } | 503   } | 
| 431 | 504 | 
| 432   void printClass(const ClassInfo& cls) | 505   void printClass(const ClassInfo& cls) | 
| 433   { | 506   { | 
| 434     // Begin class definition | 507     // Begin class definition | 
| 435 |  | 
| 436     ClassInfo* baseClass = find_class(cls.baseClass); | 508     ClassInfo* baseClass = find_class(cls.baseClass); | 
| 437     printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 509     printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 
| 438         (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 510         (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 
| 439         cls.ref_counted_offset); | 511         cls.ref_counted_offset); | 
| 440 | 512 | 
| 441     // Print prototype members | 513     // Print prototype members | 
| 442 | 514     printProperties(cls.properties); | 
| 443     for (const auto& property : cls.properties) | 515     printMethods(cls.methods); | 
| 444     { |  | 
| 445       if (property.jsValue.empty()) |  | 
| 446       { |  | 
| 447         printf("get %s%s,\n", property.name.c_str(), |  | 
| 448                wrapCall(property.getter, false).c_str()); |  | 
| 449         if (!property.setter.empty()) |  | 
| 450         { |  | 
| 451           printf("set %s%s,\n", property.name.c_str(), |  | 
| 452                  wrapCall(property.setter, false).c_str()); |  | 
| 453         } |  | 
| 454       } |  | 
| 455       else |  | 
| 456         printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); |  | 
| 457     } |  | 
| 458 |  | 
| 459     for (const auto& method : cls.methods) |  | 
| 460       if (method.call.instance_function) |  | 
| 461         printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); |  | 
| 462 | 516 | 
| 463     // End class definition | 517     // End class definition | 
| 464 |  | 
| 465     printf("});\n"); | 518     printf("});\n"); | 
| 466 | 519 | 
| 467     // Print static members | 520     // Print static members | 
| 468 |  | 
| 469     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 521     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 
| 470     if (differentiator.offset != SIZE_MAX) | 522     if (differentiator.offset != SIZE_MAX) | 
| 471     { | 523     { | 
| 472       printf("var %s_mapping = \n", cls.name.c_str()); | 524       printf("var %s_mapping = \n", cls.name.c_str()); | 
| 473       puts("{"); | 525       puts("{"); | 
| 474       for (const auto& item : differentiator.mapping) | 526       for (const auto& item : differentiator.mapping) | 
| 475         printf("  %i: '%s',\n", item.first, item.second.c_str()); | 527         printf("  %i: '%s',\n", item.first, item.second.c_str()); | 
| 476       puts("};"); | 528       puts("};"); | 
| 477 | 529 | 
| 478       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 530       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 493 | 545 | 
| 494     for (const auto& method : cls.methods) | 546     for (const auto& method : cls.methods) | 
| 495     { | 547     { | 
| 496       if (!method.call.instance_function) | 548       if (!method.call.instance_function) | 
| 497       { | 549       { | 
| 498         printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), | 550         printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), | 
| 499                wrapCall(method.call).c_str()); | 551                wrapCall(method.call).c_str()); | 
| 500       } | 552       } | 
| 501     } | 553     } | 
| 502   } | 554   } | 
|  | 555 | 
|  | 556   void printNamespace(const NamespaceInfo& namespaceInfo) | 
|  | 557   { | 
|  | 558     printf("exports.%s = {\n", namespaceInfo.name.c_str()); | 
|  | 559     printProperties(namespaceInfo.properties); | 
|  | 560     printMethods(namespaceInfo.methods, false); | 
|  | 561     puts("};"); | 
|  | 562   } | 
| 503 } | 563 } | 
| 504 | 564 | 
| 505 void printBindings() | 565 void printBindings() | 
| 506 { | 566 { | 
| 507   bindings_internal::printHelpers(); | 567   bindings_internal::printHelpers(); | 
| 508 | 568 | 
| 509   for (const auto& item : classes) | 569   for (const auto& item : classes) | 
| 510     bindings_internal::printClass(item); | 570     bindings_internal::printClass(item); | 
|  | 571   for (const auto& item : namespaces) | 
|  | 572     bindings_internal::printNamespace(item); | 
| 511 } | 573 } | 
| OLD | NEW | 
|---|