Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: compiled/bindings.ipp

Issue 29398655: Issue 5062 - [emscripten] Allow generation of custom bindings code (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Rebased Created April 13, 2017, 1:06 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « compiled/bindings.cpp ('k') | compiled/filter/RegExpFilter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « compiled/bindings.cpp ('k') | compiled/filter/RegExpFilter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld