| Left: | ||
| Right: | 
| 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 #pragma once | 18 #pragma once | 
| 19 | 19 | 
| 20 #include <cstddef> | 20 #include <cstddef> | 
| 21 #include <cstdint> | 21 #include <cstdint> | 
| 22 #include <cstdio> | 22 #include <cstdio> | 
| 23 #include <cstdlib> | 23 #include <cstdlib> | 
| 24 #include <exception> | 24 #include <exception> | 
| 25 #include <functional> | |
| 25 #include <map> | 26 #include <map> | 
| 26 #include <string> | 27 #include <string> | 
| 27 #include <type_traits> | 28 #include <type_traits> | 
| 28 #include <utility> | 29 #include <utility> | 
| 29 #include <vector> | 30 #include <vector> | 
| 30 | 31 | 
| 31 #include <emscripten.h> | 32 #include <emscripten.h> | 
| 32 | 33 | 
| 33 #include "String.h" | 34 #include "String.h" | 
| 34 #include "intrusive_ptr.h" | 35 #include "intrusive_ptr.h" | 
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 size_t offset; | 302 size_t offset; | 
| 302 std::vector<std::pair<int, std::string>> mapping; | 303 std::vector<std::pair<int, std::string>> mapping; | 
| 303 }; | 304 }; | 
| 304 | 305 | 
| 305 struct ClassInfo | 306 struct ClassInfo | 
| 306 { | 307 { | 
| 307 ClassInfo* baseClass; | 308 ClassInfo* baseClass; | 
| 308 std::string name; | 309 std::string name; | 
| 309 std::vector<PropertyInfo> properties; | 310 std::vector<PropertyInfo> properties; | 
| 310 std::vector<MethodInfo> methods; | 311 std::vector<MethodInfo> methods; | 
| 311 std::vector<FunctionInfo> initializers; | |
| 312 DifferentiatorInfo subclass_differentiator; | 312 DifferentiatorInfo subclass_differentiator; | 
| 313 ptrdiff_t ref_counted_offset; | 313 ptrdiff_t ref_counted_offset; | 
| 314 }; | 314 }; | 
| 315 | 315 | 
| 316 typedef std::function<void()> CustomGenerator; | |
| 317 | |
| 316 std::map<TYPEID, ClassInfo> classes; | 318 std::map<TYPEID, ClassInfo> classes; | 
| 319 std::vector<CustomGenerator> customGenerators; | |
| 
 
sergei
2017/04/11 16:29:20
These global variables can also contribute into li
 
Wladimir Palant
2017/04/11 18:22:44
Ok, I can see your point. Yes, they are currently
 
 | |
| 317 | 320 | 
| 318 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 321 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 
| 319 ptrdiff_t ref_counted_offset) | 322 ptrdiff_t ref_counted_offset) | 
| 320 { | 323 { | 
| 321 auto it = classes.find(classID); | 324 auto it = classes.find(classID); | 
| 322 if (it != classes.end()) | 325 if (it != classes.end()) | 
| 323 throw std::runtime_error(std::string("Duplicate definition for class ") + name); | 326 throw std::runtime_error(std::string("Duplicate definition for class ") + name); | 
| 324 | 327 | 
| 325 ClassInfo* baseClass = nullptr; | 328 ClassInfo* baseClass = nullptr; | 
| 326 if (baseClassID != TypeInfo<NoBaseClass>()) | 329 if (baseClassID != TypeInfo<NoBaseClass>()) | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 auto it = classes.find(classID); | 364 auto it = classes.find(classID); | 
| 362 if (it == classes.end()) | 365 if (it == classes.end()) | 
| 363 throw std::runtime_error(std::string("Method defined on unknown class: ") + name); | 366 throw std::runtime_error(std::string("Method defined on unknown class: ") + name); | 
| 364 | 367 | 
| 365 MethodInfo methodInfo; | 368 MethodInfo methodInfo; | 
| 366 methodInfo.name = name; | 369 methodInfo.name = name; | 
| 367 methodInfo.call = call; | 370 methodInfo.call = call; | 
| 368 it->second.methods.push_back(methodInfo); | 371 it->second.methods.push_back(methodInfo); | 
| 369 } | 372 } | 
| 370 | 373 | 
| 371 void register_initializer(TYPEID classID, const FunctionInfo& call) | |
| 372 { | |
| 373 auto it = classes.find(classID); | |
| 374 if (it == classes.end()) | |
| 375 throw std::runtime_error("Initializer defined on unknown class"); | |
| 376 | |
| 377 it->second.initializers.push_back(call); | |
| 378 } | |
| 379 | |
| 380 void register_differentiator(TYPEID classID, size_t offset, | 374 void register_differentiator(TYPEID classID, size_t offset, | 
| 381 std::vector<std::pair<int, std::string>>& mapping) | 375 std::vector<std::pair<int, std::string>>& mapping) | 
| 382 { | 376 { | 
| 383 auto it = classes.find(classID); | 377 auto it = classes.find(classID); | 
| 384 if (it == classes.end()) | 378 if (it == classes.end()) | 
| 385 throw std::runtime_error("Subclass differentiator defined on unknown class "); | 379 throw std::runtime_error("Subclass differentiator defined on unknown class "); | 
| 386 | 380 | 
| 387 if (it->second.subclass_differentiator.offset != SIZE_MAX) | 381 if (it->second.subclass_differentiator.offset != SIZE_MAX) | 
| 388 throw std::runtime_error("More than one subclass differentiator defined fo r class " + it->second.name); | 382 throw std::runtime_error("More than one subclass differentiator defined fo r class " + it->second.name); | 
| 389 | 383 | 
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 } | 590 } | 
| 597 | 591 | 
| 598 for (const auto& item : cls.methods) | 592 for (const auto& item : cls.methods) | 
| 599 { | 593 { | 
| 600 std::string obj("exports." + cls.name); | 594 std::string obj("exports." + cls.name); | 
| 601 if (item.call.instance_function) | 595 if (item.call.instance_function) | 
| 602 obj += ".prototype"; | 596 obj += ".prototype"; | 
| 603 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), | 597 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), | 
| 604 wrapCall(item.call).c_str()); | 598 wrapCall(item.call).c_str()); | 
| 605 } | 599 } | 
| 606 | |
| 607 for (const auto& item : cls.initializers) | |
| 608 printf("%s()\n", item.name); | |
| 609 } | 600 } | 
| 610 | 601 | 
| 611 void printBindings() | 602 void printBindings() | 
| 612 { | 603 { | 
| 613 printHelpers(); | 604 printHelpers(); | 
| 614 | 605 | 
| 615 for (const auto& item : classes) | 606 for (const auto& item : classes) | 
| 616 printClass(item.second); | 607 printClass(item.second); | 
| 608 | |
| 609 for (const auto& item : customGenerators) | |
| 610 item(); | |
| 617 } | 611 } | 
| 618 } | 612 } | 
| 619 | 613 | 
| 620 #if defined(PRINT_BINDINGS) | 614 #if defined(PRINT_BINDINGS) | 
| 621 // Bindings generation step: collect bindings information and print | 615 // Bindings generation step: collect bindings information and print | 
| 622 // corresponding JS code. | 616 // corresponding JS code. | 
| 623 #define EMSCRIPTEN_BINDINGS \ | 617 #define EMSCRIPTEN_BINDINGS \ | 
| 624 struct BindingsInitializer {\ | 618 void InitializeBindings();\ | 
| 625 BindingsInitializer();\ | 619 int main()\ | 
| 626 BindingsInitializer(bool dummy)\ | 620 {\ | 
| 627 {\ | 621 try\ | 
| 628 try\ | 622 {\ | 
| 629 {\ | 623 InitializeBindings();\ | 
| 630 BindingsInitializer();\ | 624 bindings_internal::printBindings();\ | 
| 631 bindings_internal::printBindings();\ | 625 }\ | 
| 632 }\ | 626 catch (const std::exception& e)\ | 
| 633 catch (const std::exception& e)\ | 627 {\ | 
| 634 {\ | 628 EM_ASM_ARGS(\ | 
| 635 EM_ASM_ARGS(\ | 629 console.error("Error occurred generating JavaScript bindings: " +\ | 
| 636 console.error("Error occurred generating JavaScript bindings: " +\ | 630 Module.AsciiToString($0)), e.what()\ | 
| 637 Module.AsciiToString($0)), e.what()\ | 631 );\ | 
| 638 );\ | 632 abort();\ | 
| 639 abort();\ | 633 }\ | 
| 640 }\ | 634 return 0;\ | 
| 641 }\ | 635 }\ | 
| 642 } BindingsInitializer_instance(true);\ | 636 void InitializeBindings() | 
| 643 BindingsInitializer::BindingsInitializer() | |
| 644 #else | 637 #else | 
| 645 // Actual compilation step: ignore bindings information but define some | 638 // Actual compilation step: ignore bindings information but define some | 
| 646 // exported helper functions necessary for the bindings. | 639 // exported helper functions necessary for the bindings. | 
| 647 #define EMSCRIPTEN_BINDINGS \ | 640 #define EMSCRIPTEN_BINDINGS \ | 
| 648 extern "C"\ | 641 extern "C"\ | 
| 649 {\ | 642 {\ | 
| 650 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ | 643 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ | 
| 651 String::value_type* data, String::size_type len)\ | 644 String::value_type* data, String::size_type len)\ | 
| 652 {\ | 645 {\ | 
| 653 /* String is already allocated on stack, we merely need to call*/\ | 646 /* String is already allocated on stack, we merely need to call*/\ | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 } | 727 } | 
| 735 | 728 | 
| 736 template<typename ReturnType, typename... Args> | 729 template<typename ReturnType, typename... Args> | 
| 737 const class_& class_function(const char* name, ReturnType (*method)(Args...)) const | 730 const class_& class_function(const char* name, ReturnType (*method)(Args...)) const | 
| 738 { | 731 { | 
| 739 bindings_internal::register_method( | 732 bindings_internal::register_method( | 
| 740 bindings_internal::TypeInfo<ClassType>(), name, method); | 733 bindings_internal::TypeInfo<ClassType>(), name, method); | 
| 741 return *this; | 734 return *this; | 
| 742 } | 735 } | 
| 743 | 736 | 
| 744 const class_& class_initializer(void (*function)()) const | |
| 745 { | |
| 746 bindings_internal::register_initializer( | |
| 747 bindings_internal::TypeInfo<ClassType>(), function); | |
| 748 return *this; | |
| 749 } | |
| 750 | |
| 751 template<typename ReturnType, | 737 template<typename ReturnType, | 
| 752 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>:: type* = nullptr> | 738 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>:: type* = nullptr> | 
| 753 const class_& subclass_differentiator(ReturnType ClassType::* member, | 739 const class_& subclass_differentiator(ReturnType ClassType::* member, | 
| 754 std::initializer_list<std::pair<ReturnType, const char*>> list) const | 740 std::initializer_list<std::pair<ReturnType, const char*>> list) const | 
| 755 { | 741 { | 
| 756 ClassType* instance = nullptr; | 742 ClassType* instance = nullptr; | 
| 757 size_t offset = (char*)&(instance->*member) - (char*)instance; | 743 size_t offset = (char*)&(instance->*member) - (char*)instance; | 
| 758 | 744 | 
| 759 std::vector<std::pair<int, std::string>> mapping; | 745 std::vector<std::pair<int, std::string>> mapping; | 
| 760 for (const auto& item : list) | 746 for (const auto& item : list) | 
| 761 mapping.emplace_back(item.first, item.second); | 747 mapping.emplace_back(item.first, item.second); | 
| 762 | 748 | 
| 763 bindings_internal::register_differentiator( | 749 bindings_internal::register_differentiator( | 
| 764 bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 750 bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 
| 765 return *this; | 751 return *this; | 
| 766 } | 752 } | 
| 767 }; | 753 }; | 
| 754 | |
| 755 void custom_generator(bindings_internal::CustomGenerator generator) | |
| 756 { | |
| 757 bindings_internal::customGenerators.push_back(generator); | |
| 758 } | |
| OLD | NEW |