Index: compiled/bindings/generator.cpp |
=================================================================== |
--- a/compiled/bindings/generator.cpp |
+++ b/compiled/bindings/generator.cpp |
@@ -248,17 +248,17 @@ 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; |
} |
- const std::string generateCall(const FunctionInfo& call, |
+ 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"); |
} |
@@ -319,21 +319,25 @@ namespace bindings_internal |
result += " result = null;\n"; |
return result; |
} |
default: |
throw std::runtime_error("Unexpected return type for " + std::string(call.name)); |
} |
} |
- const std::string wrapCall(const FunctionInfo& call) |
+ std::string wrapCall(const FunctionInfo& call, bool isFunction) |
{ |
bool hasStringArgs = false; |
std::vector<std::string> params; |
- std::string prefix = "function("; |
+ std::string prefix; |
+ |
+ if (isFunction) |
+ prefix += "function"; |
+ prefix += "("; |
for (int i = 0; i < call.args.size(); i++) |
{ |
std::string argName("arg" + std::to_string(i)); |
if (i > 0) |
prefix += ", "; |
prefix += argName; |
if (call.args[i] == TypeCategory::STRING_REF) |
@@ -366,27 +370,16 @@ namespace bindings_internal |
} |
if (call.instance_function) |
params.insert(params.begin(), "this._pointer"); |
return prefix + generateCall(call, params) + suffix; |
} |
- std::string generatePropertyDescriptor(const PropertyInfo& property) |
- { |
- if (!property.jsValue.empty()) |
- return "value: " + property.jsValue; |
- |
- std::string result("get: " + wrapCall(property.getter)); |
- if (!property.setter.empty()) |
- result += ", set: " + wrapCall(property.setter); |
- return result; |
- } |
- |
void printHelpers() |
{ |
printf("var sizeofString = %i;\n", sizeof(String)); |
puts(R"( |
function copyString(str, buffer) |
{ |
var length = str.length; |
@@ -412,40 +405,70 @@ namespace bindings_internal |
function readString(str) |
{ |
var length = Module._GetStringLength(str); |
var pointer = Module._GetStringData(str) >> 1; |
return String.fromCharCode.apply(String, HEAP16.slice(pointer, pointer + length)); |
} |
- function createClass(superclass, ref_counted_offset) |
+ function createClass(superclass, ref_counted_offset, props) |
{ |
var result = function(pointer) |
{ |
this._pointer = pointer; |
}; |
- if (superclass) |
- result.prototype = Object.create(superclass.prototype); |
+ var proto = (superclass ? superclass.prototype : null); |
+ result.prototype = Object.create(proto, Object.getOwnPropertyDescriptors(props)); |
result.prototype.delete = function() |
{ |
Module._ReleaseRef(this._pointer + ref_counted_offset); |
}; |
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(), |
+ 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()); |
+ |
+ // 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("};"); |
@@ -461,30 +484,23 @@ namespace bindings_internal |
else |
{ |
printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); |
puts("{"); |
printf(" return new exports.%s(ptr);\n", cls.name.c_str()); |
puts("};"); |
} |
- for (const auto& item : cls.properties) |
+ for (const auto& method : cls.methods) |
{ |
- printf("Object.defineProperty(exports.%s.prototype, '%s', {%s});\n", |
- cls.name.c_str(), item.name.c_str(), |
- generatePropertyDescriptor(item).c_str()); |
- } |
- |
- 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()); |
+ 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 printBindings() |
{ |
bindings_internal::printHelpers(); |