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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 size_t offset; | 330 size_t offset; |
330 std::vector<std::pair<int, std::string>> mapping; | 331 std::vector<std::pair<int, std::string>> mapping; |
331 }; | 332 }; |
332 | 333 |
333 struct ClassInfo | 334 struct ClassInfo |
334 { | 335 { |
335 ClassInfo* baseClass; | 336 ClassInfo* baseClass; |
336 std::string name; | 337 std::string name; |
337 std::vector<PropertyInfo> properties; | 338 std::vector<PropertyInfo> properties; |
338 std::vector<MethodInfo> methods; | 339 std::vector<MethodInfo> methods; |
339 std::vector<FunctionInfo> initializers; | |
340 DifferentiatorInfo subclass_differentiator; | 340 DifferentiatorInfo subclass_differentiator; |
341 ptrdiff_t ref_counted_offset; | 341 ptrdiff_t ref_counted_offset; |
342 }; | 342 }; |
343 | 343 |
| 344 typedef std::function<void()> CustomGenerator; |
| 345 |
344 std::map<TYPEID, ClassInfo> classes; | 346 std::map<TYPEID, ClassInfo> classes; |
| 347 std::vector<CustomGenerator> customGenerators; |
345 | 348 |
346 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 349 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, |
347 ptrdiff_t ref_counted_offset) | 350 ptrdiff_t ref_counted_offset) |
348 { | 351 { |
349 auto it = classes.find(classID); | 352 auto it = classes.find(classID); |
350 if (it != classes.end()) | 353 if (it != classes.end()) |
351 throw std::runtime_error(std::string("Duplicate definition for class ") +
name); | 354 throw std::runtime_error(std::string("Duplicate definition for class ") +
name); |
352 | 355 |
353 ClassInfo* baseClass = nullptr; | 356 ClassInfo* baseClass = nullptr; |
354 if (baseClassID != TypeInfo<NoBaseClass>()) | 357 if (baseClassID != TypeInfo<NoBaseClass>()) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 auto it = classes.find(classID); | 392 auto it = classes.find(classID); |
390 if (it == classes.end()) | 393 if (it == classes.end()) |
391 throw std::runtime_error(std::string("Method defined on unknown class: ")
+ name); | 394 throw std::runtime_error(std::string("Method defined on unknown class: ")
+ name); |
392 | 395 |
393 MethodInfo methodInfo; | 396 MethodInfo methodInfo; |
394 methodInfo.name = name; | 397 methodInfo.name = name; |
395 methodInfo.call = call; | 398 methodInfo.call = call; |
396 it->second.methods.push_back(methodInfo); | 399 it->second.methods.push_back(methodInfo); |
397 } | 400 } |
398 | 401 |
399 void register_initializer(TYPEID classID, const FunctionInfo& call) | |
400 { | |
401 auto it = classes.find(classID); | |
402 if (it == classes.end()) | |
403 throw std::runtime_error("Initializer defined on unknown class"); | |
404 | |
405 it->second.initializers.push_back(call); | |
406 } | |
407 | |
408 void register_differentiator(TYPEID classID, size_t offset, | 402 void register_differentiator(TYPEID classID, size_t offset, |
409 std::vector<std::pair<int, std::string>>& mapping) | 403 std::vector<std::pair<int, std::string>>& mapping) |
410 { | 404 { |
411 auto it = classes.find(classID); | 405 auto it = classes.find(classID); |
412 if (it == classes.end()) | 406 if (it == classes.end()) |
413 throw std::runtime_error("Subclass differentiator defined on unknown class
"); | 407 throw std::runtime_error("Subclass differentiator defined on unknown class
"); |
414 | 408 |
415 if (it->second.subclass_differentiator.offset != SIZE_MAX) | 409 if (it->second.subclass_differentiator.offset != SIZE_MAX) |
416 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + it->second.name); | 410 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + it->second.name); |
417 | 411 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 } | 627 } |
634 | 628 |
635 for (const auto& item : cls.methods) | 629 for (const auto& item : cls.methods) |
636 { | 630 { |
637 std::string obj("exports." + cls.name); | 631 std::string obj("exports." + cls.name); |
638 if (item.call.instance_function) | 632 if (item.call.instance_function) |
639 obj += ".prototype"; | 633 obj += ".prototype"; |
640 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), | 634 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), |
641 wrapCall(item.call).c_str()); | 635 wrapCall(item.call).c_str()); |
642 } | 636 } |
643 | |
644 for (const auto& item : cls.initializers) | |
645 printf("%s()\n", item.name); | |
646 } | 637 } |
647 | 638 |
648 void printBindings() | 639 void printBindings() |
649 { | 640 { |
650 printHelpers(); | 641 printHelpers(); |
651 | 642 |
652 for (const auto& item : classes) | 643 for (const auto& item : classes) |
653 printClass(item.second); | 644 printClass(item.second); |
| 645 |
| 646 for (const auto& item : customGenerators) |
| 647 item(); |
654 } | 648 } |
655 } | 649 } |
656 | 650 |
657 #if defined(PRINT_BINDINGS) | 651 #if defined(PRINT_BINDINGS) |
658 // Bindings generation step: collect bindings information and print | 652 // Bindings generation step: collect bindings information and print |
659 // corresponding JS code. | 653 // corresponding JS code. |
660 #define EMSCRIPTEN_BINDINGS \ | 654 #define EMSCRIPTEN_BINDINGS \ |
661 struct BindingsInitializer {\ | 655 void InitializeBindings();\ |
662 BindingsInitializer();\ | 656 int main()\ |
663 BindingsInitializer(bool dummy)\ | 657 {\ |
664 {\ | 658 try\ |
665 try\ | 659 {\ |
666 {\ | 660 InitializeBindings();\ |
667 BindingsInitializer();\ | 661 bindings_internal::printBindings();\ |
668 bindings_internal::printBindings();\ | 662 }\ |
669 }\ | 663 catch (const std::exception& e)\ |
670 catch (const std::exception& e)\ | 664 {\ |
671 {\ | 665 EM_ASM_ARGS(\ |
672 EM_ASM_ARGS(\ | 666 console.error("Error occurred generating JavaScript bindings: " +\ |
673 console.error("Error occurred generating JavaScript bindings: "
+\ | 667 Module.AsciiToString($0)), e.what()\ |
674 Module.AsciiToString($0)), e.what()\ | 668 );\ |
675 );\ | 669 abort();\ |
676 abort();\ | 670 }\ |
677 }\ | 671 return 0;\ |
678 }\ | 672 }\ |
679 } BindingsInitializer_instance(true);\ | 673 void InitializeBindings() |
680 BindingsInitializer::BindingsInitializer() | |
681 #else | 674 #else |
682 // Actual compilation step: ignore bindings information but define some | 675 // Actual compilation step: ignore bindings information but define some |
683 // exported helper functions necessary for the bindings. | 676 // exported helper functions necessary for the bindings. |
684 #define EMSCRIPTEN_BINDINGS \ | 677 #define EMSCRIPTEN_BINDINGS \ |
685 extern "C"\ | 678 extern "C"\ |
686 {\ | 679 {\ |
687 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ | 680 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ |
688 String::value_type* data, String::size_type len)\ | 681 String::value_type* data, String::size_type len)\ |
689 {\ | 682 {\ |
690 /* String is already allocated on stack, we merely need to call*/\ | 683 /* String is already allocated on stack, we merely need to call*/\ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 } | 764 } |
772 | 765 |
773 template<typename ReturnType, typename... Args> | 766 template<typename ReturnType, typename... Args> |
774 const class_& class_function(const char* name, ReturnType (*method)(Args...))
const | 767 const class_& class_function(const char* name, ReturnType (*method)(Args...))
const |
775 { | 768 { |
776 bindings_internal::register_method( | 769 bindings_internal::register_method( |
777 bindings_internal::TypeInfo<ClassType>(), name, method); | 770 bindings_internal::TypeInfo<ClassType>(), name, method); |
778 return *this; | 771 return *this; |
779 } | 772 } |
780 | 773 |
781 const class_& class_initializer(void (*function)()) const | |
782 { | |
783 bindings_internal::register_initializer( | |
784 bindings_internal::TypeInfo<ClassType>(), function); | |
785 return *this; | |
786 } | |
787 | |
788 template<typename ReturnType, | 774 template<typename ReturnType, |
789 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::
type* = nullptr> | 775 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::
type* = nullptr> |
790 const class_& subclass_differentiator(ReturnType ClassType::* member, | 776 const class_& subclass_differentiator(ReturnType ClassType::* member, |
791 std::initializer_list<std::pair<ReturnType, const char*>> list) const | 777 std::initializer_list<std::pair<ReturnType, const char*>> list) const |
792 { | 778 { |
793 ClassType* instance = nullptr; | 779 ClassType* instance = nullptr; |
794 size_t offset = (char*)&(instance->*member) - (char*)instance; | 780 size_t offset = (char*)&(instance->*member) - (char*)instance; |
795 | 781 |
796 std::vector<std::pair<int, std::string>> mapping; | 782 std::vector<std::pair<int, std::string>> mapping; |
797 for (const auto& item : list) | 783 for (const auto& item : list) |
798 mapping.emplace_back(item.first, item.second); | 784 mapping.emplace_back(item.first, item.second); |
799 | 785 |
800 bindings_internal::register_differentiator( | 786 bindings_internal::register_differentiator( |
801 bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 787 bindings_internal::TypeInfo<ClassType>(), offset, mapping); |
802 return *this; | 788 return *this; |
803 } | 789 } |
804 }; | 790 }; |
| 791 |
| 792 void custom_generator(bindings_internal::CustomGenerator generator) |
| 793 { |
| 794 bindings_internal::customGenerators.push_back(generator); |
| 795 } |
OLD | NEW |