| Index: compiled/bindings/generator.cpp |
| =================================================================== |
| --- a/compiled/bindings/generator.cpp |
| +++ b/compiled/bindings/generator.cpp |
| @@ -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) |
| + const 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(); |