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

Unified Diff: compiled/bindings/generator.cpp

Issue 29426559: Issue 5137 - [emscripten] Added basic filter storage implementation (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Created May 1, 2017, 2:36 p.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/generator.cpp
===================================================================
--- a/compiled/bindings/generator.cpp
+++ b/compiled/bindings/generator.cpp
@@ -19,16 +19,44 @@
#include <emscripten.h>
#include "generator.h"
namespace
{
std::vector<bindings_internal::ClassInfo> classes;
+ std::vector<bindings_internal::NamespaceInfo> namespaces;
+
+ void printProperties(const bindings_internal::PropertyList& properties)
+ {
+ for (const auto& property : properties)
+ {
+ if (property.jsValue.empty())
+ {
+ printf("get %s%s,\n", property.name.c_str(),
+ wrapCall(property.getter, false).c_str());
+ if (!property.setter.empty())
+ {
+ printf("set %s%s,\n", property.name.c_str(),
+ wrapCall(property.setter, false).c_str());
+ }
+ }
+ else
+ printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str());
+ }
+ }
+
+ void printMethods(const bindings_internal::MethodList& methods,
+ bool instanceOnly = true)
+ {
+ for (const auto& method : methods)
+ if (!instanceOnly || method.call.instance_function)
+ printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str());
+ }
}
namespace bindings_internal
{
FunctionInfo::FunctionInfo()
{
name[0] = '\0';
}
@@ -250,16 +278,61 @@ namespace bindings_internal
throw std::runtime_error("More than one subclass differentiator defined for class " + classInfo->name);
DifferentiatorInfo differentiatorInfo;
differentiatorInfo.offset = offset;
differentiatorInfo.mapping = mapping;
classInfo->subclass_differentiator = differentiatorInfo;
}
+ NamespaceInfo* find_namespace(const char* namespaceName)
+ {
+ for (auto& namespaceInfo : namespaces)
+ if (namespaceInfo.name == namespaceName)
+ return &namespaceInfo;
+ return nullptr;
+ }
+
+ void register_namespace(const char* name)
+ {
+ if (find_namespace(name))
+ throw std::runtime_error(std::string("Duplicate definition for namespace ") + name);
+
+ NamespaceInfo namespaceInfo;
+ namespaceInfo.name = name;
+ namespaces.push_back(namespaceInfo);
+ }
+
+ void register_namespace_property(const char* namespaceName, const char* name,
+ const FunctionInfo& getter, const FunctionInfo& setter)
+ {
+ NamespaceInfo* namespaceInfo = find_namespace(namespaceName);
+ if (!namespaceInfo)
+ throw std::runtime_error(std::string("Property defined on unknown namespace: ") + name);
+
+ PropertyInfo propertyInfo;
+ propertyInfo.name = name;
+ propertyInfo.getter = getter;
+ propertyInfo.setter = setter;
+ namespaceInfo->properties.push_back(propertyInfo);
+ }
+
+ void register_namespace_method(const char* namespaceName, const char* name,
+ const FunctionInfo& call)
+ {
+ NamespaceInfo* namespaceInfo = find_namespace(namespaceName);
+ if (!namespaceInfo)
+ throw std::runtime_error(std::string("Method defined on unknown namespace: ") + name);
+
+ MethodInfo methodInfo;
+ methodInfo.name = name;
+ methodInfo.call = call;
+ namespaceInfo->methods.push_back(methodInfo);
+ }
Wladimir Palant 2017/05/01 14:47:25 I'm not really happy with the complexity required
sergei 2017/05/08 10:54:39 I would like to include in that discussion the des
Wladimir Palant 2017/05/08 12:55:41 I considered making FilterStorage a singleton clas
sergei 2017/08/24 13:32:04 Singleton and global variables are actually equall
+
std::string generateCall(const FunctionInfo& call,
std::vector<std::string>& params)
{
if (call.returnType == TypeCategory::DEPENDENT_STRING ||
call.returnType == TypeCategory::OWNED_STRING)
{
params.insert(params.begin(), "string");
}
@@ -343,17 +416,17 @@ namespace bindings_internal
prefix += argName;
if (call.args[i] == TypeCategory::STRING_REF)
{
hasStringArgs = true;
params.push_back(std::string("createString(") + argName + ")");
}
else if (call.args[i] == TypeCategory::CLASS_PTR)
- params.push_back(argName + "._pointer");
+ params.push_back(argName + " ? " + argName + "._pointer : 0");
Wladimir Palant 2017/05/01 14:47:25 Turns out we weren't supporting null for parameter
sergei 2017/05/08 10:54:39 In addition I wonder whether we can use C++ refere
Wladimir Palant 2017/05/08 12:55:41 We could use references easily but these won't be
sergei 2017/08/24 13:32:04 Currently one has to manually test whether a point
Wladimir Palant 2017/08/31 11:32:34 I filed https://issues.adblockplus.org/ticket/5603
else if (call.args[i] == TypeCategory::INT64)
{
// 64-bit integers are passed as two integer parameters
params.push_back(argName + " >>> 0");
params.push_back(argName + " / 0x100000000 >>> 0");
}
else
params.push_back(argName);
@@ -427,50 +500,29 @@ namespace bindings_internal
return result;
}
)");
}
void printClass(const ClassInfo& cls)
{
// Begin class definition
-
ClassInfo* baseClass = find_class(cls.baseClass);
printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(),
(baseClass ? ("exports." + baseClass->name).c_str() : "null"),
cls.ref_counted_offset);
// Print prototype members
-
- for (const auto& property : cls.properties)
- {
- if (property.jsValue.empty())
- {
- printf("get %s%s,\n", property.name.c_str(),
- wrapCall(property.getter, false).c_str());
- if (!property.setter.empty())
- {
- printf("set %s%s,\n", property.name.c_str(),
- wrapCall(property.setter, false).c_str());
- }
- }
- else
- printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str());
- }
-
- for (const auto& method : cls.methods)
- if (method.call.instance_function)
- printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str());
+ printProperties(cls.properties);
+ printMethods(cls.methods);
// End class definition
-
printf("});\n");
// Print static members
-
DifferentiatorInfo differentiator = cls.subclass_differentiator;
if (differentiator.offset != SIZE_MAX)
{
printf("var %s_mapping = \n", cls.name.c_str());
puts("{");
for (const auto& item : differentiator.mapping)
printf(" %i: '%s',\n", item.first, item.second.c_str());
puts("};");
@@ -495,17 +547,27 @@ namespace bindings_internal
{
if (!method.call.instance_function)
{
printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(),
wrapCall(method.call).c_str());
}
}
}
+
+ void printNamespace(const NamespaceInfo& namespaceInfo)
+ {
+ printf("exports.%s = {\n", namespaceInfo.name.c_str());
+ printProperties(namespaceInfo.properties);
+ printMethods(namespaceInfo.methods, false);
+ puts("};");
+ }
}
void printBindings()
{
bindings_internal::printHelpers();
for (const auto& item : classes)
bindings_internal::printClass(item);
+ for (const auto& item : namespaces)
+ bindings_internal::printNamespace(item);
}

Powered by Google App Engine
This is Rietveld