зеркало из https://github.com/mozilla/pluotsorbet.git
289 строки
8.5 KiB
TypeScript
289 строки
8.5 KiB
TypeScript
///<reference path='build/j2me-jsc.d.ts' />
|
|
|
|
var jsGlobal = (function() { return this || (1, eval)('this'); })();
|
|
|
|
if (!jsGlobal.performance) {
|
|
jsGlobal.performance = {};
|
|
}
|
|
|
|
if (!jsGlobal.performance.now) {
|
|
jsGlobal.performance.now = typeof dateNow !== 'undefined' ? dateNow : Date.now;
|
|
}
|
|
|
|
declare var load: (string) => void;
|
|
|
|
load("libs/relooper.js"); // Load before we polyfill the window object.
|
|
|
|
var CC = {};
|
|
|
|
// Define objects and functions that j2me.js expects
|
|
// but are unavailable in the shell environment.
|
|
|
|
jsGlobal.window = {
|
|
setZeroTimeout: function(callback) {
|
|
callback();
|
|
},
|
|
addEventListener: function() {
|
|
},
|
|
crypto: {
|
|
getRandomValues: function() {
|
|
},
|
|
},
|
|
};
|
|
|
|
jsGlobal.navigator = {
|
|
language: "en-US",
|
|
};
|
|
|
|
jsGlobal.document = {
|
|
documentElement: {
|
|
classList: {
|
|
add: function() {
|
|
},
|
|
},
|
|
},
|
|
querySelector: function() {
|
|
return {
|
|
addEventListener: function() {
|
|
},
|
|
};
|
|
},
|
|
getElementById: function() {
|
|
return {
|
|
addEventListener: function() {
|
|
},
|
|
getContext: function() {
|
|
},
|
|
getBoundingClientRect: function() {
|
|
return { top: 0, left: 0, width: 0, height: 0 };
|
|
}
|
|
};
|
|
},
|
|
addEventListener: function() {
|
|
},
|
|
};
|
|
|
|
jsGlobal.config = {
|
|
logConsole: "native",
|
|
args: "",
|
|
};
|
|
|
|
jsGlobal.Promise = function() {
|
|
}
|
|
|
|
module J2ME {
|
|
declare var process, require, global, quit, help, scriptArgs, arguments, snarf, ZipFile, JARStore;
|
|
|
|
var isNode = typeof process === 'object';
|
|
var writer: IndentingWriter;
|
|
var rootPath = "";
|
|
|
|
function loadFiles(...files: string[]) {
|
|
for (var i = 0; i < files.length; i++) {
|
|
load(rootPath + files[i]);
|
|
}
|
|
}
|
|
|
|
loadFiles("libs/long.js", "blackBox.js", "build/j2me-jsc.js", "libs/zipfile.js", "libs/jarstore.js", "libs/encoding.js", "util.js");
|
|
|
|
phase = ExecutionPhase.Compiler;
|
|
|
|
writer = new IndentingWriter();
|
|
|
|
var verboseOption: Options.Option;
|
|
var classpathOption: Options.Option;
|
|
var callGraphOption: Options.Option;
|
|
var jarFileFilterOption: Options.Option;
|
|
var classFileFilterOption: Options.Option;
|
|
var classFilterOption: Options.Option;
|
|
var methodFilterOption: Options.Option;
|
|
var methodFileFilterOption: Options.Option;
|
|
var fileFilterOption: Options.Option;
|
|
var debuggerOption: Options.Option;
|
|
var releaseOption: Options.Option;
|
|
|
|
|
|
function main(commandLineArguments: string []) {
|
|
var options = new Options.OptionSet("J2ME");
|
|
var shellOptions = options.register(new Options.OptionSet(""));
|
|
|
|
verboseOption = shellOptions.register(new Options.Option("v", "verbose", "boolean", false, "Verbose"));
|
|
classpathOption = shellOptions.register(new Options.Option("cp", "classpath", "string []", [], "Compile ClassPath"));
|
|
callGraphOption = shellOptions.register(new Options.Option("cg", "callGraph", "string []", [], "Call Grpah Files"));
|
|
|
|
|
|
jarFileFilterOption = shellOptions.register(new Options.Option("jf", "jarFileFilter", "string", "", "Compile Jar File Filter"));
|
|
classFileFilterOption = shellOptions.register(new Options.Option("cff", "classFileFilter", "string", "", "Compile Class File Filter"));
|
|
methodFileFilterOption = shellOptions.register(new Options.Option("mff", "methodFileFilter", "string", "", "Compile Metgod File Filter"));
|
|
classFilterOption = shellOptions.register(new Options.Option("cf", "classFilter", "string", ".*", "Compile Class Filter"));
|
|
methodFilterOption = shellOptions.register(new Options.Option("mf", "methodFilter", "string", "", "Compile Method Filter"));
|
|
|
|
fileFilterOption = shellOptions.register(new Options.Option("ff", "fileFilter", "string", ".*", "Compile File Filter"));
|
|
debuggerOption = shellOptions.register(new Options.Option("d", "debugger", "boolean", false, "Emit Debug Information"));
|
|
releaseOption = shellOptions.register(new Options.Option("r", "release", "boolean", false, "Release mode"));
|
|
|
|
var argumentParser = new Options.ArgumentParser();
|
|
argumentParser.addBoundOptionSet(shellOptions);
|
|
|
|
function printUsage() {
|
|
writer.enter("J2ME Command Line Interface");
|
|
options.trace(writer);
|
|
writer.leave("");
|
|
}
|
|
|
|
argumentParser.addArgument("h", "help", "boolean", {
|
|
parse: function (x) {
|
|
printUsage();
|
|
}
|
|
});
|
|
|
|
var files = [];
|
|
|
|
// Try and parse command line arguments.
|
|
|
|
try {
|
|
argumentParser.parse(commandLineArguments);
|
|
classpathOption.value.filter(function (value, index, array) {
|
|
if (value.endsWith(".jar")) {
|
|
files.push(value);
|
|
} else {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
callGraphOption.value.filter(function (value, index, array) {
|
|
if (value.endsWith(".json")) {
|
|
var calls = JSON.parse(snarf(value));
|
|
var Y = {};
|
|
Y["java/io/ByteArrayOutputStream.write.(I)V"] = true;
|
|
var changed = true;
|
|
while (changed) {
|
|
changed = false;
|
|
for (var k in calls) {
|
|
if (Y[k]) {
|
|
continue;
|
|
}
|
|
for (var z in Y) {
|
|
if (calls[k].indexOf(z) >= 0) {
|
|
Y[k] = true;
|
|
changed = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
writer.writeLn(JSON.stringify(Y, null, 2));
|
|
} else {
|
|
return true;
|
|
}
|
|
});
|
|
} catch (x) {
|
|
writer.writeLn(x.message);
|
|
writer.writeLns(x.stack);
|
|
quit();
|
|
}
|
|
|
|
var jarFiles = Object.create(null);
|
|
|
|
var jvm = new JVM();
|
|
for (var i = 0; i < files.length; i++) {
|
|
var file = files[i];
|
|
if (file.endsWith(".jar")) {
|
|
if (verboseOption.value) {
|
|
writer.writeLn("Loading: " + file);
|
|
}
|
|
var data = snarf(file, "binary").buffer
|
|
JARStore.addBuiltIn(file, data);
|
|
jarFiles[file] = new ZipFile(data);
|
|
}
|
|
}
|
|
CLASSES.initializeBuiltinClasses();
|
|
Bytecode.defineBytecodes();
|
|
if (verboseOption.value) {
|
|
writer.writeLn("Compiling Pattern: " + classFilterOption.value + " " + classFileFilterOption.value + " " + methodFileFilterOption.value);
|
|
}
|
|
var classNameList;
|
|
if (classFileFilterOption.value) {
|
|
var file;
|
|
try {
|
|
file = snarf(classFileFilterOption.value, "text");
|
|
} catch (e) {
|
|
|
|
}
|
|
if (file) {
|
|
classNameList = file.replace(/\r?\n/g, "\n").split("\n");
|
|
}
|
|
}
|
|
var methodFilterList = null;
|
|
if (methodFileFilterOption.value) {
|
|
var file;
|
|
try {
|
|
file = snarf(methodFileFilterOption.value, "text");
|
|
} catch (e) {
|
|
|
|
}
|
|
if (file) {
|
|
methodFilterList = [];
|
|
var lines = file.replace(/\r?\n/g, "\n").split("\n");
|
|
for (var i = 0; i < lines.length; i++) {
|
|
// Trim Whitespace
|
|
var line = lines[i].replace(/^\s+|\s+$/g, "");
|
|
if (line === "") {
|
|
continue;
|
|
}
|
|
methodFilterList.push(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
function jarFilter(file): boolean {
|
|
if (jarFileFilterOption.value) {
|
|
return file === jarFileFilterOption.value;
|
|
}
|
|
return true;
|
|
}
|
|
function classFilter(classInfo: ClassInfo): boolean {
|
|
if (classNameList) {
|
|
return classNameList.indexOf(classInfo.getClassNameSlow()) >= 0;
|
|
} else if (classFilterOption.value) {
|
|
return !!classInfo.getClassNameSlow().match(classFilterOption.value);
|
|
}
|
|
return false;
|
|
}
|
|
if (methodFilterOption.value) {
|
|
methodFilterList = [methodFilterOption.value];
|
|
}
|
|
|
|
stdoutWriter.writeLn("var start = performance.now();");
|
|
compile(jvm, jarFiles, jarFilter, classFilter, methodFilterList, fileFilterOption.value, debuggerOption.value);
|
|
stdoutWriter.writeLn("console.log(\"Loaded " + jarFileFilterOption.value + " in \" + (performance.now() - start).toFixed(2) + \" ms.\");");
|
|
if (methodFilterList !== null && methodFilterList.length) {
|
|
stderrWriter.enter("The following method(s) in the method filter list failed to compile or were not found:");
|
|
for (var i = 0; i < methodFilterList.length; i++) {
|
|
stderrWriter.errorLn(methodFilterList[i]);
|
|
}
|
|
stderrWriter.leave("");
|
|
}
|
|
if (verboseOption.value) {
|
|
// ...
|
|
}
|
|
}
|
|
|
|
var commandLineArguments: string [];
|
|
// Shell Entry Point
|
|
if (typeof help === "function") {
|
|
// SpiderMonkey
|
|
if (typeof scriptArgs === "undefined") {
|
|
commandLineArguments = arguments;
|
|
} else {
|
|
commandLineArguments = scriptArgs;
|
|
}
|
|
} else if (isNode) {
|
|
// node.js
|
|
var commandLineArguments: string[] =
|
|
Array.prototype.slice.call(process.argv, 2);
|
|
}
|
|
|
|
main(commandLineArguments);
|
|
}
|