diff --git a/jdk.js b/jdk.js index bc08665..621d928 100755 --- a/jdk.js +++ b/jdk.js @@ -50,7 +50,7 @@ async init(root) { this.root = root || 'https://unpkg.com/java2js'; this.java = {}; - let pkgs = ['com', 'lang', 'org', 'io', 'util', 'time']; + let pkgs = ['com', 'io', 'lang', 'org', 'security', 'time', 'util']; for (let pkg of pkgs) { this.java[pkg] = {}; } @@ -106,8 +106,8 @@ // this.launch(); // } - launch() { - this.main(this.jvmArgs); + run(jvmArgs) { + this.main(jvmArgs); } getClass(classPath) { @@ -171,7 +171,7 @@ async translate(file) { if (!this.java) { console.error( - 'java2js error: JDK not initialized! You must call `await jdk.init()` before using `jdk.run()`' + 'java2js error: JDK not initialized! You must call `await jdk.init()` before using `jdk.load()`' ); } let classLine = file.indexOf('public class'); @@ -193,6 +193,8 @@ return 'new Array(' + p2.replace(/\{([^\}]*)\}/gm, 'new Array($1)') + ')'; }); + file = file.replace(/new\s*\w*\s*\[\s*(\d)+\s*\]\s*/gm, 'new Array($1)'); + // workaround hack for converting lambda expressions to Runnables let lambdaRegex = /\(\)\s*\->\s*\{(([^\{\}]*\{[^\}]*\})*[^\}]*)\}/g; @@ -244,7 +246,7 @@ // handle Java class imports for (let i = 0; i < imports.length; i++) { let imp = imports[i]; - // skip static imports for now (like QuintOS) + // skip static imports for now if (imp.includes('static')) continue; let impPath = imp.split('.'); let impName = impPath[impPath.length - 1]; @@ -256,14 +258,16 @@ } prefix += '\n'; - let suffix = `\nwindow.${className} = ${className};\njdk.main = ${className}.main;\njdk.launch();\n})();`; + let suffix = '\n'; + suffix += `window.${className} = ${className};\n`; + suffix += '})();'; trans = prefix + trans + suffix; return trans; } - run(trans) { + load(trans) { return new Promise(async (resolve, reject) => { const script = document.createElement('script'); script.async = false; @@ -19424,6 +19428,7 @@ staticVars.push(`${className}.${name}=(...args${SEP})=>{switch(args${SEP}.length){${cases}}};`); else classProps.push(`${name}(...args${SEP}){switch(args${SEP}.length){${cases}}}`); } + if (name == 'main') staticVars.push(`jdk.main = ${className}.main;`); } if (!addedConstructor && initVars.length) classProps.unshift(`constructor(){${initVars.join('')}}`); diff --git a/jdk/java/io/PrintStream.js b/jdk/java/io/PrintStream.js index ea73627..8f62689 100755 --- a/jdk/java/io/PrintStream.js +++ b/jdk/java/io/PrintStream.js @@ -1,4 +1,6 @@ jdk.imports['java.io.PrintStream'].load = async () => { + const MessageDigest = await jdk.import('java.security.MessageDigest'); + class PrintStream { constructor() { this.log = ''; @@ -13,31 +15,47 @@ jdk.imports['java.io.PrintStream'].load = async () => { this.onPrint(length); } - print(arg) { - let str = arg.toString(); - this.log += str; - if (window?.ide) { - ide.log.value += str; - this._onPrint(str.length); + _printArray(arr) { + let md = MessageDigest.getInstance(); + let str = '[Ljava.lang.'; + let hash = md.digest(arr.toString()).slice(0, 8); + if (arr.length == 0) { + return str + 'Array;@' + hash; + } + if (typeof arr[0] == 'string') { + return str + 'String;@' + hash; + } else { + return str + 'Number;@' + hash; } } - println(arg) { - let str = arg.toString() + '\n'; + _print(arg, ln) { + let str; + if (Array.isArray(arg)) { + str = this._printArray(arg); + } else { + str = arg.toString(); + } + if (ln) str += '\n'; this.log += str; if (window?.ide) { ide.log.value += str; this._onPrint(str.length); } + return str; + } + + print(arg) { + return this._print(arg); + } + + println(arg) { + return this._print(arg, true); } printf(format, ...args) { let str = String.format(format, args); - this.log += str; - if (window?.ide) { - ide.log.value += str; - this._onPrint(str.length); - } + return this._print(str); } } jdk.java.io.PrintStream = PrintStream; diff --git a/jdk/java/lang/String.js b/jdk/java/lang/String.js index e6a51e1..d962470 100755 --- a/jdk/java/lang/String.js +++ b/jdk/java/lang/String.js @@ -3,15 +3,16 @@ jdk.imports['java.lang.String'].load = async () => { // String is special, I just extended js String prototype String.prototype.hashCode = function () { - let h = this._hashCode; - if (!h && this.length > 0) { - const val = this; - for (let i = 0; i < this.length; i++) { - h = 31 * h + this.charCodeAt(i); - } - this._hashCode = h; + var hash = 0, + i, + chr; + if (this.length === 0) return hash; + for (i = 0; i < this.length; i++) { + chr = this.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; // Convert to 32bit integer } - return h; + return hash; }; String.prototype.isEmpty = function () { return this.length == 0; diff --git a/jdk/java/security/MessageDigest.js b/jdk/java/security/MessageDigest.js new file mode 100644 index 0000000..135e737 --- /dev/null +++ b/jdk/java/security/MessageDigest.js @@ -0,0 +1,423 @@ +jdk.imports['java.security.MessageDigest'].load = async () => { + class MessageDigest { + constructor(algorithm) { + this.algorithm = algorithm; + + // SOURCE: https://stackoverflow.com/a/33486055/3792062 + this.MD5 = function (d) { + var r = M(V(Y(X(d), 8 * d.length))); + return r.toLowerCase(); + }; + function M(d) { + for (var _, m = '0123456789ABCDEF', f = '', r = 0; r < d.length; r++) + (_ = d.charCodeAt(r)), (f += m.charAt((_ >>> 4) & 15) + m.charAt(15 & _)); + return f; + } + function X(d) { + for (var _ = Array(d.length >> 2), m = 0; m < _.length; m++) _[m] = 0; + for (m = 0; m < 8 * d.length; m += 8) _[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32; + return _; + } + function V(d) { + for (var _ = '', m = 0; m < 32 * d.length; m += 8) _ += String.fromCharCode((d[m >> 5] >>> m % 32) & 255); + return _; + } + function Y(d, _) { + (d[_ >> 5] |= 128 << _ % 32), (d[14 + (((_ + 64) >>> 9) << 4)] = _); + for (var m = 1732584193, f = -271733879, r = -1732584194, i = 271733878, n = 0; n < d.length; n += 16) { + var h = m, + t = f, + g = r, + e = i; + (f = md5_ii( + (f = md5_ii( + (f = md5_ii( + (f = md5_ii( + (f = md5_hh( + (f = md5_hh( + (f = md5_hh( + (f = md5_hh( + (f = md5_gg( + (f = md5_gg( + (f = md5_gg( + (f = md5_gg( + (f = md5_ff( + (f = md5_ff( + (f = md5_ff( + (f = md5_ff( + f, + (r = md5_ff( + r, + (i = md5_ff( + i, + (m = md5_ff(m, f, r, i, d[n + 0], 7, -680876936)), + f, + r, + d[n + 1], + 12, + -389564586 + )), + m, + f, + d[n + 2], + 17, + 606105819 + )), + i, + m, + d[n + 3], + 22, + -1044525330 + )), + (r = md5_ff( + r, + (i = md5_ff( + i, + (m = md5_ff(m, f, r, i, d[n + 4], 7, -176418897)), + f, + r, + d[n + 5], + 12, + 1200080426 + )), + m, + f, + d[n + 6], + 17, + -1473231341 + )), + i, + m, + d[n + 7], + 22, + -45705983 + )), + (r = md5_ff( + r, + (i = md5_ff( + i, + (m = md5_ff(m, f, r, i, d[n + 8], 7, 1770035416)), + f, + r, + d[n + 9], + 12, + -1958414417 + )), + m, + f, + d[n + 10], + 17, + -42063 + )), + i, + m, + d[n + 11], + 22, + -1990404162 + )), + (r = md5_ff( + r, + (i = md5_ff( + i, + (m = md5_ff(m, f, r, i, d[n + 12], 7, 1804603682)), + f, + r, + d[n + 13], + 12, + -40341101 + )), + m, + f, + d[n + 14], + 17, + -1502002290 + )), + i, + m, + d[n + 15], + 22, + 1236535329 + )), + (r = md5_gg( + r, + (i = md5_gg( + i, + (m = md5_gg(m, f, r, i, d[n + 1], 5, -165796510)), + f, + r, + d[n + 6], + 9, + -1069501632 + )), + m, + f, + d[n + 11], + 14, + 643717713 + )), + i, + m, + d[n + 0], + 20, + -373897302 + )), + (r = md5_gg( + r, + (i = md5_gg( + i, + (m = md5_gg(m, f, r, i, d[n + 5], 5, -701558691)), + f, + r, + d[n + 10], + 9, + 38016083 + )), + m, + f, + d[n + 15], + 14, + -660478335 + )), + i, + m, + d[n + 4], + 20, + -405537848 + )), + (r = md5_gg( + r, + (i = md5_gg( + i, + (m = md5_gg(m, f, r, i, d[n + 9], 5, 568446438)), + f, + r, + d[n + 14], + 9, + -1019803690 + )), + m, + f, + d[n + 3], + 14, + -187363961 + )), + i, + m, + d[n + 8], + 20, + 1163531501 + )), + (r = md5_gg( + r, + (i = md5_gg( + i, + (m = md5_gg(m, f, r, i, d[n + 13], 5, -1444681467)), + f, + r, + d[n + 2], + 9, + -51403784 + )), + m, + f, + d[n + 7], + 14, + 1735328473 + )), + i, + m, + d[n + 12], + 20, + -1926607734 + )), + (r = md5_hh( + r, + (i = md5_hh( + i, + (m = md5_hh(m, f, r, i, d[n + 5], 4, -378558)), + f, + r, + d[n + 8], + 11, + -2022574463 + )), + m, + f, + d[n + 11], + 16, + 1839030562 + )), + i, + m, + d[n + 14], + 23, + -35309556 + )), + (r = md5_hh( + r, + (i = md5_hh( + i, + (m = md5_hh(m, f, r, i, d[n + 1], 4, -1530992060)), + f, + r, + d[n + 4], + 11, + 1272893353 + )), + m, + f, + d[n + 7], + 16, + -155497632 + )), + i, + m, + d[n + 10], + 23, + -1094730640 + )), + (r = md5_hh( + r, + (i = md5_hh( + i, + (m = md5_hh(m, f, r, i, d[n + 13], 4, 681279174)), + f, + r, + d[n + 0], + 11, + -358537222 + )), + m, + f, + d[n + 3], + 16, + -722521979 + )), + i, + m, + d[n + 6], + 23, + 76029189 + )), + (r = md5_hh( + r, + (i = md5_hh( + i, + (m = md5_hh(m, f, r, i, d[n + 9], 4, -640364487)), + f, + r, + d[n + 12], + 11, + -421815835 + )), + m, + f, + d[n + 15], + 16, + 530742520 + )), + i, + m, + d[n + 2], + 23, + -995338651 + )), + (r = md5_ii( + r, + (i = md5_ii(i, (m = md5_ii(m, f, r, i, d[n + 0], 6, -198630844)), f, r, d[n + 7], 10, 1126891415)), + m, + f, + d[n + 14], + 15, + -1416354905 + )), + i, + m, + d[n + 5], + 21, + -57434055 + )), + (r = md5_ii( + r, + (i = md5_ii(i, (m = md5_ii(m, f, r, i, d[n + 12], 6, 1700485571)), f, r, d[n + 3], 10, -1894986606)), + m, + f, + d[n + 10], + 15, + -1051523 + )), + i, + m, + d[n + 1], + 21, + -2054922799 + )), + (r = md5_ii( + r, + (i = md5_ii(i, (m = md5_ii(m, f, r, i, d[n + 8], 6, 1873313359)), f, r, d[n + 15], 10, -30611744)), + m, + f, + d[n + 6], + 15, + -1560198380 + )), + i, + m, + d[n + 13], + 21, + 1309151649 + )), + (r = md5_ii( + r, + (i = md5_ii(i, (m = md5_ii(m, f, r, i, d[n + 4], 6, -145523070)), f, r, d[n + 11], 10, -1120210379)), + m, + f, + d[n + 2], + 15, + 718787259 + )), + i, + m, + d[n + 9], + 21, + -343485551 + )), + (m = safe_add(m, h)), + (f = safe_add(f, t)), + (r = safe_add(r, g)), + (i = safe_add(i, e)); + } + return Array(m, f, r, i); + } + function md5_cmn(d, _, m, f, r, i) { + return safe_add(bit_rol(safe_add(safe_add(_, d), safe_add(f, i)), r), m); + } + function md5_ff(d, _, m, f, r, i, n) { + return md5_cmn((_ & m) | (~_ & f), d, _, r, i, n); + } + function md5_gg(d, _, m, f, r, i, n) { + return md5_cmn((_ & f) | (m & ~f), d, _, r, i, n); + } + function md5_hh(d, _, m, f, r, i, n) { + return md5_cmn(_ ^ m ^ f, d, _, r, i, n); + } + function md5_ii(d, _, m, f, r, i, n) { + return md5_cmn(m ^ (_ | ~f), d, _, r, i, n); + } + function safe_add(d, _) { + var m = (65535 & d) + (65535 & _); + return (((d >> 16) + (_ >> 16) + (m >> 16)) << 16) | (65535 & m); + } + function bit_rol(d, _) { + return (d << _) | (d >>> (32 - _)); + } + } + digest(str) { + return this.MD5(str); + } + } + MessageDigest.getInstance = (algorithm) => { + return new MessageDigest(algorithm); + }; + jdk.java.security.MessageDigest = MessageDigest; +}; diff --git a/package.json b/package.json index 6f830f8..8102ac6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "java2js", - "version": "1.0.11", + "version": "1.0.12", "description": "Converts Java to JavaScript with support for p5.js and QuintOS.", "main": "jdk.js", "scripts": {