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: Fixed mistakenly exported function Created April 11, 2017, 6:17 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
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