Index: lib/compiledTools.js |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/lib/compiledTools.js |
@@ -0,0 +1,121 @@ |
+"use strict"; |
+ |
+let { |
+ Runtime, AsciiToString, HEAP16, HEAP32, _free, _getException |
+} = require("./compiled"); |
+ |
+function createClass(superclass) |
+{ |
+ let result = function(pointer) |
+ { |
+ this._pointer = pointer; |
+ }; |
+ if (superclass) |
+ result.prototype = Object.create(superclass.prototype); |
+ return result; |
+} |
+exports.createClass = createClass; |
+ |
+function wrapCall(call) |
+{ |
+ return function() |
+ { |
+ let sp = Runtime.stackSave(); |
+ try |
+ { |
+ return call.apply(this, arguments); |
+ } |
+ catch (e) |
+ { |
+ throw typeof e == "number" ? new Error(AsciiToString(_getException(e))) : e; |
+ } |
+ finally |
+ { |
+ Runtime.stackRestore(sp); |
+ } |
+ }; |
+} |
+exports.wrapCall = wrapCall; |
+ |
+function convertString(str) |
+{ |
+ let length = str.length; |
+ let buffer = Runtime.stackAlloc(length * 2); |
+ for (let i = 0, pointer = (buffer >> 1); i < length; i++, pointer++) |
+ HEAP16[pointer] = str.charCodeAt(i); |
+ return buffer; |
+} |
+ |
+function stringArg(argNumber, call) |
+{ |
+ return function() |
+ { |
+ let params = Array.slice(arguments); |
+ let str = params[argNumber]; |
+ if (str != null) |
+ params.splice(argNumber, 1, convertString(str), str.length); |
+ else |
+ params.splice(argNumber, 1, 0, 0); |
+ return call.apply(this, params); |
+ }; |
+} |
+exports.stringArg = stringArg; |
+ |
+function stringResult(call) |
+{ |
+ return function() |
+ { |
+ let params = Array.slice(arguments); |
+ let resultLen = Runtime.stackAlloc(4); |
+ params.push(resultLen); |
+ |
+ let buffer = call.apply(this, params); |
+ if (buffer) |
+ { |
+ let length = HEAP32[resultLen >> 2]; |
+ let pointer = buffer >> 1; |
+ let str = String.fromCharCode.apply(String, HEAP16.slice(pointer, pointer + length)); |
+ _free(buffer); |
+ return str; |
+ } |
+ else |
+ return null; |
+ }; |
+} |
+exports.stringResult = stringResult; |
+ |
+function _convertGetter(call) |
+{ |
+ return function() |
+ { |
+ return call(this._pointer); |
+ }; |
+} |
+ |
+function _convertSetter(call) |
+{ |
+ return function(value) |
+ { |
+ call(this._pointer, value); |
+ } |
+} |
+ |
+function defineProperty(cls, name, getter, setter) |
+{ |
+ let descriptor = |
+ { |
+ enumerable: true, |
+ get: wrapCall(_convertGetter(getter)) |
+ }; |
+ if (setter) |
+ descriptor.set = wrapCall(_convertSetter(setter)); |
+ Object.defineProperty(cls.prototype, name, descriptor); |
+} |
+exports.defineProperty = defineProperty; |
+ |
+function defineStringProperty(cls, name, getter, setter) |
+{ |
+ defineProperty(cls, name, stringResult(getter), |
+ (setter ? stringArg(1, setter) : null)); |
+} |
+exports.defineStringProperty = defineStringProperty; |