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

Unified 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: Created March 30, 2017, 7:59 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiled/bindings.ipp
===================================================================
--- a/compiled/bindings.ipp
+++ b/compiled/bindings.ipp
@@ -17,16 +17,17 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <exception>
+#include <functional>
#include <map>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <emscripten.h>
@@ -303,22 +304,24 @@ namespace bindings_internal
};
struct ClassInfo
{
ClassInfo* baseClass;
std::string name;
std::vector<PropertyInfo> properties;
std::vector<MethodInfo> methods;
- std::vector<FunctionInfo> initializers;
DifferentiatorInfo subclass_differentiator;
ptrdiff_t ref_counted_offset;
};
+ typedef std::function<void()> CustomGenerator;
+
std::map<TYPEID, ClassInfo> classes;
+ std::vector<CustomGenerator> customGenerators;
void register_class(const char* name, TYPEID classID, TYPEID baseClassID,
ptrdiff_t ref_counted_offset)
{
auto it = classes.find(classID);
if (it != classes.end())
throw std::runtime_error(std::string("Duplicate definition for class ") + name);
@@ -363,25 +366,16 @@ namespace bindings_internal
throw std::runtime_error(std::string("Method defined on unknown class: ") + name);
MethodInfo methodInfo;
methodInfo.name = name;
methodInfo.call = call;
it->second.methods.push_back(methodInfo);
}
- void register_initializer(TYPEID classID, const FunctionInfo& call)
- {
- auto it = classes.find(classID);
- if (it == classes.end())
- throw std::runtime_error("Initializer defined on unknown class");
-
- it->second.initializers.push_back(call);
- }
-
void register_differentiator(TYPEID classID, size_t offset,
std::vector<std::pair<int, std::string>>& mapping)
{
auto it = classes.find(classID);
if (it == classes.end())
throw std::runtime_error("Subclass differentiator defined on unknown class");
if (it->second.subclass_differentiator.offset != SIZE_MAX)
@@ -598,53 +592,54 @@ namespace bindings_internal
for (const auto& item : cls.methods)
{
std::string obj("exports." + cls.name);
if (item.call.instance_function)
obj += ".prototype";
printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(),
wrapCall(item.call).c_str());
}
-
- for (const auto& item : cls.initializers)
- printf("%s()\n", item.name);
}
void printBindings()
{
printHelpers();
for (const auto& item : classes)
printClass(item.second);
+
+ for (const auto& item : customGenerators)
+ item();
}
}
#if defined(PRINT_BINDINGS)
// Bindings generation step: collect bindings information and print
// corresponding JS code.
#define EMSCRIPTEN_BINDINGS \
struct BindingsInitializer {\
BindingsInitializer();\
- BindingsInitializer(bool dummy)\
- {\
- try\
- {\
- BindingsInitializer();\
- bindings_internal::printBindings();\
- }\
- catch (const std::exception& e)\
- {\
- EM_ASM_ARGS(\
- console.error("Error occurred generating JavaScript bindings: " +\
- Module.AsciiToString($0)), e.what()\
- );\
- abort();\
- }\
- }\
- } BindingsInitializer_instance(true);\
+ };\
sergei 2017/03/30 11:09:17 I would make it a simple function `void Initialize
Wladimir Palant 2017/03/30 12:58:58 Done.
+ int main(void)\
sergei 2017/03/30 11:09:17 In C++ there is no need for specifying of void in
sergei 2017/03/30 11:09:17 Do you mind to consider in future moving of such C
Wladimir Palant 2017/03/30 12:58:58 Done.
Wladimir Palant 2017/03/30 12:58:58 Not sure what you mean. This code is inside bindin
sergei 2017/04/04 14:49:30 I mean it would be better to have this code in ano
Wladimir Palant 2017/04/04 15:41:48 But we are not compiling an executable, it's not s
sergei 2017/04/11 16:29:20 I didn't mean to append a cpp with main to SOURCE_
Wladimir Palant 2017/04/11 18:22:44 Let's do this in a follow-up, I'll file an issue.
+ {\
+ try\
+ {\
+ struct BindingsInitializer instance;\
sergei 2017/03/30 11:09:17 Why did you need to add struct here?
Wladimir Palant 2017/03/30 12:58:57 This is a InitializeBindings() call now - this was
+ bindings_internal::printBindings();\
+ }\
+ catch (const std::exception& e)\
+ {\
+ EM_ASM_ARGS(\
+ console.error("Error occurred generating JavaScript bindings: " +\
+ Module.AsciiToString($0)), e.what()\
+ );\
+ abort();\
+ }\
+ return 0;\
+ }\
BindingsInitializer::BindingsInitializer()
#else
// Actual compilation step: ignore bindings information but define some
// exported helper functions necessary for the bindings.
#define EMSCRIPTEN_BINDINGS \
extern "C"\
{\
void EMSCRIPTEN_KEEPALIVE InitString(DependentString* str,\
@@ -736,23 +731,16 @@ public:
template<typename ReturnType, typename... Args>
const class_& class_function(const char* name, ReturnType (*method)(Args...)) const
{
bindings_internal::register_method(
bindings_internal::TypeInfo<ClassType>(), name, method);
return *this;
}
- const class_& class_initializer(void (*function)()) const
- {
- bindings_internal::register_initializer(
- bindings_internal::TypeInfo<ClassType>(), function);
- return *this;
- }
-
template<typename ReturnType,
typename std::enable_if<std::is_convertible<ReturnType, int32_t>::value>::type* = nullptr>
const class_& subclass_differentiator(ReturnType ClassType::* member,
std::initializer_list<std::pair<ReturnType, const char*>> list) const
{
ClassType* instance = nullptr;
size_t offset = (char*)&(instance->*member) - (char*)instance;
@@ -760,8 +748,13 @@ public:
for (const auto& item : list)
mapping.emplace_back(item.first, item.second);
bindings_internal::register_differentiator(
bindings_internal::TypeInfo<ClassType>(), offset, mapping);
return *this;
}
};
+
+void custom_generator(bindings_internal::CustomGenerator generator)
+{
+ bindings_internal::customGenerators.push_back(generator);
+}

Powered by Google App Engine
This is Rietveld