| 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; |