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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 size_t offset; | 305 size_t offset; |
305 std::vector<std::pair<int, std::string>> mapping; | 306 std::vector<std::pair<int, std::string>> mapping; |
306 }; | 307 }; |
307 | 308 |
308 struct ClassInfo | 309 struct ClassInfo |
309 { | 310 { |
310 ClassInfo* baseClass; | 311 ClassInfo* baseClass; |
311 std::string name; | 312 std::string name; |
312 std::vector<PropertyInfo> properties; | 313 std::vector<PropertyInfo> properties; |
313 std::vector<MethodInfo> methods; | 314 std::vector<MethodInfo> methods; |
314 std::vector<FunctionInfo> initializers; | |
315 DifferentiatorInfo subclass_differentiator; | 315 DifferentiatorInfo subclass_differentiator; |
316 ptrdiff_t ref_counted_offset; | 316 ptrdiff_t ref_counted_offset; |
317 }; | 317 }; |
318 | 318 |
| 319 typedef std::function<void()> CustomGenerator; |
| 320 |
319 std::map<TYPEID, ClassInfo> classes; | 321 std::map<TYPEID, ClassInfo> classes; |
| 322 std::vector<CustomGenerator> customGenerators; |
320 | 323 |
321 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 324 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, |
322 ptrdiff_t ref_counted_offset) | 325 ptrdiff_t ref_counted_offset) |
323 { | 326 { |
324 auto it = classes.find(classID); | 327 auto it = classes.find(classID); |
325 if (it != classes.end()) | 328 if (it != classes.end()) |
326 throw std::runtime_error(std::string("Duplicate definition for class ") +
name); | 329 throw std::runtime_error(std::string("Duplicate definition for class ") +
name); |
327 | 330 |
328 ClassInfo* baseClass = nullptr; | 331 ClassInfo* baseClass = nullptr; |
329 if (baseClassID != TypeInfo<NoBaseClass>()) | 332 if (baseClassID != TypeInfo<NoBaseClass>()) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 auto it = classes.find(classID); | 367 auto it = classes.find(classID); |
365 if (it == classes.end()) | 368 if (it == classes.end()) |
366 throw std::runtime_error(std::string("Method defined on unknown class: ")
+ name); | 369 throw std::runtime_error(std::string("Method defined on unknown class: ")
+ name); |
367 | 370 |
368 MethodInfo methodInfo; | 371 MethodInfo methodInfo; |
369 methodInfo.name = name; | 372 methodInfo.name = name; |
370 methodInfo.call = call; | 373 methodInfo.call = call; |
371 it->second.methods.push_back(methodInfo); | 374 it->second.methods.push_back(methodInfo); |
372 } | 375 } |
373 | 376 |
374 void register_initializer(TYPEID classID, const FunctionInfo& call) | |
375 { | |
376 auto it = classes.find(classID); | |
377 if (it == classes.end()) | |
378 throw std::runtime_error("Initializer defined on unknown class"); | |
379 | |
380 it->second.initializers.push_back(call); | |
381 } | |
382 | |
383 void register_differentiator(TYPEID classID, size_t offset, | 377 void register_differentiator(TYPEID classID, size_t offset, |
384 std::vector<std::pair<int, std::string>>& mapping) | 378 std::vector<std::pair<int, std::string>>& mapping) |
385 { | 379 { |
386 auto it = classes.find(classID); | 380 auto it = classes.find(classID); |
387 if (it == classes.end()) | 381 if (it == classes.end()) |
388 throw std::runtime_error("Subclass differentiator defined on unknown class
"); | 382 throw std::runtime_error("Subclass differentiator defined on unknown class
"); |
389 | 383 |
390 if (it->second.subclass_differentiator.offset != SIZE_MAX) | 384 if (it->second.subclass_differentiator.offset != SIZE_MAX) |
391 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + it->second.name); | 385 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + it->second.name); |
392 | 386 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 } | 606 } |
613 | 607 |
614 for (const auto& item : cls.methods) | 608 for (const auto& item : cls.methods) |
615 { | 609 { |
616 std::string obj("exports." + cls.name); | 610 std::string obj("exports." + cls.name); |
617 if (item.call.instance_function) | 611 if (item.call.instance_function) |
618 obj += ".prototype"; | 612 obj += ".prototype"; |
619 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), | 613 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), |
620 wrapCall(item.call).c_str()); | 614 wrapCall(item.call).c_str()); |
621 } | 615 } |
622 | |
623 for (const auto& item : cls.initializers) | |
624 printf("%s()\n", item.name); | |
625 } | 616 } |
626 | 617 |
627 void printBindings() | 618 void printBindings() |
628 { | 619 { |
629 printHelpers(); | 620 printHelpers(); |
630 | 621 |
631 for (const auto& item : classes) | 622 for (const auto& item : classes) |
632 printClass(item.second); | 623 printClass(item.second); |
| 624 |
| 625 for (const auto& item : customGenerators) |
| 626 item(); |
633 } | 627 } |
634 } | 628 } |
635 | 629 |
636 #if defined(PRINT_BINDINGS) | 630 #if defined(PRINT_BINDINGS) |
637 // Bindings generation step: collect bindings information and print | 631 // Bindings generation step: collect bindings information and print |
638 // corresponding JS code. | 632 // corresponding JS code. |
639 #define EMSCRIPTEN_BINDINGS \ | 633 #define EMSCRIPTEN_BINDINGS \ |
640 struct BindingsInitializer {\ | 634 void InitializeBindings();\ |
641 BindingsInitializer();\ | 635 int main()\ |
642 BindingsInitializer(bool dummy)\ | 636 {\ |
643 {\ | 637 try\ |
644 try\ | 638 {\ |
645 {\ | 639 InitializeBindings();\ |
646 BindingsInitializer();\ | 640 bindings_internal::printBindings();\ |
647 bindings_internal::printBindings();\ | 641 }\ |
648 }\ | 642 catch (const std::exception& e)\ |
649 catch (const std::exception& e)\ | 643 {\ |
650 {\ | 644 EM_ASM_ARGS(\ |
651 EM_ASM_ARGS(\ | 645 console.error("Error occurred generating JavaScript bindings: " +\ |
652 console.error("Error occurred generating JavaScript bindings: "
+\ | 646 Module.AsciiToString($0)), e.what()\ |
653 Module.AsciiToString($0)), e.what()\ | 647 );\ |
654 );\ | 648 abort();\ |
655 abort();\ | 649 }\ |
656 }\ | 650 return 0;\ |
657 }\ | 651 }\ |
658 } BindingsInitializer_instance(true);\ | 652 void InitializeBindings() |
659 BindingsInitializer::BindingsInitializer() | |
660 #else | 653 #else |
661 // Actual compilation step: ignore bindings information but define some | 654 // Actual compilation step: ignore bindings information but define some |
662 // exported helper functions necessary for the bindings. | 655 // exported helper functions necessary for the bindings. |
663 #define EMSCRIPTEN_BINDINGS \ | 656 #define EMSCRIPTEN_BINDINGS \ |
664 extern "C"\ | 657 extern "C"\ |
665 {\ | 658 {\ |
666 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ | 659 void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\ |
667 String::value_type* data, String::size_type len)\ | 660 String::value_type* data, String::size_type len)\ |
668 {\ | 661 {\ |
669 /* String is already allocated on stack, we merely need to call*/\ | 662 /* String is already allocated on stack, we merely need to call*/\ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 } | 743 } |
751 | 744 |
752 template<typename ReturnType, typename... Args> | 745 template<typename ReturnType, typename... Args> |
753 const class_& class_function(const char* name, ReturnType (*method)(Args...))
const | 746 const class_& class_function(const char* name, ReturnType (*method)(Args...))
const |
754 { | 747 { |
755 bindings_internal::register_method( | 748 bindings_internal::register_method( |
756 bindings_internal::TypeInfo<ClassType>(), name, method); | 749 bindings_internal::TypeInfo<ClassType>(), name, method); |
757 return *this; | 750 return *this; |
758 } | 751 } |
759 | 752 |
760 const class_& class_initializer(void (*function)()) const | |
761 { | |
762 bindings_internal::register_initializer( | |
763 bindings_internal::TypeInfo<ClassType>(), function); | |
764 return *this; | |
765 } | |
766 | |
767 template<typename ReturnType, | 753 template<typename ReturnType, |
768 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::
type* = nullptr> | 754 typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::
type* = nullptr> |
769 const class_& subclass_differentiator(ReturnType ClassType::* member, | 755 const class_& subclass_differentiator(ReturnType ClassType::* member, |
770 std::initializer_list<std::pair<ReturnType, const char*>> list) const | 756 std::initializer_list<std::pair<ReturnType, const char*>> list) const |
771 { | 757 { |
772 ClassType* instance = nullptr; | 758 ClassType* instance = nullptr; |
773 size_t offset = (char*)&(instance->*member) - (char*)instance; | 759 size_t offset = (char*)&(instance->*member) - (char*)instance; |
774 | 760 |
775 std::vector<std::pair<int, std::string>> mapping; | 761 std::vector<std::pair<int, std::string>> mapping; |
776 for (const auto& item : list) | 762 for (const auto& item : list) |
777 mapping.emplace_back(item.first, item.second); | 763 mapping.emplace_back(item.first, item.second); |
778 | 764 |
779 bindings_internal::register_differentiator( | 765 bindings_internal::register_differentiator( |
780 bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 766 bindings_internal::TypeInfo<ClassType>(), offset, mapping); |
781 return *this; | 767 return *this; |
782 } | 768 } |
783 }; | 769 }; |
| 770 |
| 771 void custom_generator(bindings_internal::CustomGenerator generator) |
| 772 { |
| 773 bindings_internal::customGenerators.push_back(generator); |
| 774 } |
OLD | NEW |