/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */ 'use strict'; var Classes = function() { if (this instanceof Classes) { this.classfiles = []; this.mainclass = []; this.classes = {}; } else { return new Classes(); } } Classes.ClassNotFoundException = function(message) { this.message = message; }; Classes.ClassNotFoundException.prototype = Object.create(Error.prototype); Classes.ClassNotFoundException.prototype.name = "ClassNotFoundException"; Classes.ClassNotFoundException.prototype.constructor = Classes.ClassNotFoundException; Classes.prototype.addPath = function(name, data) { if (name.substr(-4) === ".jar") { data = new ZipFile(data); } this.classfiles[name] = data; } Classes.prototype.loadFileFromJar = function(jar, fileName) { var classfiles = this.classfiles; var zip = classfiles[jar]; if (!zip) return null; if (!(fileName in zip.directory)) return null; var bytes = zip.read(fileName); return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); } Classes.prototype.loadFile = function(fileName) { var classfiles = this.classfiles; var data = classfiles[fileName]; if (data) return data; Object.keys(classfiles).every(function (name) { if (name.substr(-4) !== ".jar") return true; var zip = classfiles[name]; if (fileName in zip.directory) { var bytes = zip.read(fileName); data = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); } return !data; }); if (data) classfiles[fileName] = data; return data; } Classes.prototype.loadClassBytes = function(bytes) { var classInfo = new ClassInfo(bytes); this.classes[classInfo.className] = classInfo; return classInfo; } Classes.prototype.loadClassFile = function(fileName) { var bytes = this.loadFile(fileName); if (!bytes) throw new (Classes.ClassNotFoundException)(fileName); var self = this; var classInfo = this.loadClassBytes(bytes); if (classInfo.superClassName) classInfo.superClass = this.loadClass(classInfo.superClassName); var classes = classInfo.classes; classes.forEach(function (c, n) { classes[n] = self.loadClass(c); }); return classInfo; } Classes.prototype.loadClass = function(className) { var classInfo = this.classes[className]; if (classInfo) return classInfo; return this.loadClassFile(className + ".class"); } Classes.prototype.getEntryPoint = function(classInfo) { var methods = classInfo.methods; for (var i=0; i