├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── _config.yml ├── examples ├── arrays │ ├── Dog.java │ ├── Main.java │ ├── arrays.js │ └── makefile ├── cast │ ├── Main.java │ ├── cast.js │ └── makefile ├── dogs │ ├── Main.java │ ├── dogs.js │ └── makefile ├── ex │ ├── Main.java │ ├── ex.js │ └── makefile ├── ex2 │ ├── Main.java │ ├── ex.js │ └── makefile ├── fibonacci │ ├── Main.java │ ├── fibonacci.js │ └── makefile ├── idogs │ ├── Dog.java │ ├── IDog.java │ ├── Main.java │ ├── idogs.js │ └── makefile ├── jar │ ├── Main.java │ ├── fibonacci.js │ ├── makefile │ └── manifest.txt ├── jsclass │ ├── IMyJsClass.java │ ├── Main.java │ ├── MyJsClass.js │ ├── jsclass.js │ └── makefile ├── nested │ ├── Clazz.java │ ├── Main.java │ ├── makefile │ └── nested.js ├── static │ ├── Main.java │ ├── MyOut.java │ ├── MySystem.java │ ├── makefile │ └── static.js ├── switcher │ ├── Main.java │ ├── makefile │ └── switcher.js └── threads │ ├── Dog.java │ ├── Main.java │ ├── makefile │ └── threads.js ├── help.txt ├── index.js ├── libs ├── arraytypes.js ├── classes.js ├── classfile │ ├── accessflags.js │ ├── attributetypes.js │ ├── classarea.js │ ├── signature.js │ └── tags.js ├── frame.js ├── java │ ├── io │ │ ├── IOException.js │ │ └── PrintStream.js │ ├── lang │ │ ├── ArithmeticException.js │ │ ├── ArrayIndexOutOfBoundsException.js │ │ ├── ArrayStoreException.js │ │ ├── Class.js │ │ ├── ClassCastException.js │ │ ├── ClassNotFoundException.js │ │ ├── ClassNotSupportedException.js │ │ ├── Exception.js │ │ ├── IllegalArgumentException.js │ │ ├── IllegalMonitorStateException.js │ │ ├── IllegalThreadStateException.js │ │ ├── IlligalAccessException.js │ │ ├── IndexOutOfBoundsException.js │ │ ├── InstantiationException.js │ │ ├── Integer.js │ │ ├── InterruptedException.js │ │ ├── NegativeArraySizeException.js │ │ ├── NoSuchMethodException.js │ │ ├── NullPointerException.js │ │ ├── NumberFormatException.js │ │ ├── Object.js │ │ ├── RuntimeException.js │ │ ├── SecurityException.js │ │ ├── String.js │ │ ├── StringBuilder.js │ │ ├── StringIndexOutOfBoundsException.js │ │ ├── System.js │ │ ├── Thread.js │ │ └── Throwable.js │ └── util │ │ ├── EmptyStackException.js │ │ └── NoSuchElementException.js ├── jvm.js ├── logger.js ├── opcodes.js ├── scheduler.js ├── thread.js ├── threads.js └── util │ ├── globalizer.js │ ├── numeric.js │ └── reader.js ├── package.json ├── readme.md └── test ├── _basic └── Object.java ├── _static ├── Main.java └── Nested.java ├── basic_test.js └── static_test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: 2 | - node_js 3 | - java 4 | 5 | node_js: 6 | - '8.11.0' 7 | before_script: 8 | - npm install -g grunt-cli 9 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (grunt) { 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | mochaTest: { 8 | test: { 9 | options: { 10 | reporter: 'spec' 11 | }, 12 | src: ['test/**/*.js'] 13 | } 14 | } 15 | }); 16 | 17 | // These plugins provide necessary tasks. 18 | grunt.loadNpmTasks('grunt-mocha-test'); 19 | 20 | grunt.registerTask('test', 'mochaTest'); 21 | 22 | }; -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /examples/arrays/Dog.java: -------------------------------------------------------------------------------- 1 | public class Dog { 2 | private String name; 3 | 4 | public Dog(String name) { 5 | this.name = name; 6 | } 7 | 8 | public void say() { 9 | System.out.println("My name is " + name); 10 | } 11 | } -------------------------------------------------------------------------------- /examples/arrays/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | int[][][] multi = new int[20][30][40]; 5 | int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 | 7 | String[] nicks = { "Mike", "Bob", "Alex" }; 8 | 9 | Dog[] dogs = new Dog[nicks.length]; 10 | 11 | for (int i = 0; i < dogs.length; i++) { 12 | dogs[i] = new Dog(nicks[i]); 13 | } 14 | 15 | for (int i = 0; i < dogs.length; i++) { 16 | dogs[i].say(); 17 | } 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /examples/arrays/arrays.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFiles(__dirname); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/arrays/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/cast/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static long ladd(long a, long b) { 4 | return a + b; 5 | } 6 | 7 | 8 | public static double dadd(double a, double b) { 9 | return a + b; 10 | } 11 | 12 | public static void main(String[] args) { 13 | 14 | double da = 10.2; 15 | double db = -3.1; 16 | double dc = da + db; 17 | System.out.println(dc); 18 | System.out.println(dadd(da, db)); 19 | 20 | long la = 10; 21 | long lb = -3; 22 | long lc = la + lb; 23 | System.out.println(lc); 24 | System.out.println(ladd(la, lb)); 25 | 26 | byte b = 17; 27 | int i = b; 28 | long l = i; 29 | float f = l; 30 | double d = f; 31 | 32 | System.out.println(b); 33 | System.out.println(i); 34 | System.out.println(l); 35 | System.out.println(f); 36 | System.out.println(d); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/cast/cast.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/cast/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/dogs/Main.java: -------------------------------------------------------------------------------- 1 | class Animal { 2 | private String name; 3 | 4 | public Animal(String name) { 5 | this.name = name; 6 | } 7 | 8 | public void say(String message) { 9 | System.out.println(name + " says: " + message); 10 | } 11 | } 12 | 13 | class Dog extends Animal { 14 | public Dog(String name) { 15 | super(name); 16 | } 17 | } 18 | 19 | class Cat extends Animal { 20 | public Cat(String name) { 21 | super(name); 22 | } 23 | } 24 | 25 | public class Main { 26 | 27 | public static void main(String[] args) { 28 | Animal mike = new Dog("Mike"); 29 | Animal sten = new Dog("Sten"); 30 | System.out.println("mike is instanceOf Dog: " + (mike instanceof Dog)); 31 | System.out.println("sten is instanceOf Dog: " + (sten instanceof Dog)); 32 | System.out.println("sten is instanceOf Cat: " + (sten instanceof Cat)); 33 | 34 | System.out.println("mike.hashCode: " + mike.hashCode()); 35 | System.out.println("mike.toString: " + mike.toString()); 36 | System.out.println("sten.hashCode: " + sten.hashCode()); 37 | System.out.println("sten.toString: " + sten.toString()); 38 | 39 | mike.say("hello, nice day!"); 40 | sten.say("woof!"); 41 | mike.say("good bye!"); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /examples/dogs/dogs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFiles(__dirname); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/dogs/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/ex/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void ex() throws ArithmeticException { 4 | throw new ArithmeticException("This is ArithmeticException !!!"); 5 | } 6 | 7 | public static void main(String[] args) { 8 | try { 9 | System.out.println("try..."); 10 | throw new NullPointerException("This is NullPointerException !!!"); 11 | } catch (NullPointerException ex) { 12 | System.out.println("catch..."); 13 | throw new SecurityException("This is SecurityException !!!"); 14 | } finally { 15 | System.out.println("finally..."); 16 | ex(); 17 | throw new IllegalArgumentException("This is IllegalArgumentException !!!"); 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /examples/ex/ex.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/ex/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/ex2/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | { 5 | Object[] a = new Object[10]; 6 | try { 7 | Object b = a[11]; 8 | } catch (ArrayIndexOutOfBoundsException ex) { 9 | System.out.println(ex); 10 | } 11 | } 12 | { 13 | Object[] a = null; 14 | try { 15 | Object b = a[11]; 16 | } catch (NullPointerException ex) { 17 | System.out.println(ex); 18 | } 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /examples/ex2/ex.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/ex2/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/fibonacci/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static long fib(int n) { 4 | if (n <= 1) 5 | return n; 6 | return fib(n - 1) + fib(n - 2); 7 | } 8 | 9 | public static void main(String[] args) { 10 | if (args.length == 0) { 11 | System.out.print("help: java Fibonacci {Number}"); 12 | return; 13 | } 14 | 15 | int N = Integer.parseInt(args[0]); 16 | 17 | long start = System.currentTimeMillis(); 18 | System.out.format("Fibonacci from 1 to %s:\n", N); 19 | for (int i = 1; i <= N; i++) { 20 | System.out.println(i + ": " + fib(i)); 21 | } 22 | long stop = System.currentTimeMillis(); 23 | System.out.println("time: " + (stop - start) + "ms"); 24 | 25 | System.out.println("done."); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/fibonacci/fibonacci.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.setLogLevel(7); 6 | jvm.loadClassFiles(__dirname); 7 | jvm.on("exit", function(code) { 8 | process.exit(code); 9 | }); 10 | jvm.run([15]); -------------------------------------------------------------------------------- /examples/fibonacci/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/idogs/Dog.java: -------------------------------------------------------------------------------- 1 | public class Dog implements IDog { 2 | 3 | private String nick; 4 | 5 | public Dog(String nick) { 6 | this.nick = nick; 7 | } 8 | 9 | @Override 10 | public void say(String message) { 11 | System.out.println(nick + " says: " + message); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /examples/idogs/IDog.java: -------------------------------------------------------------------------------- 1 | public interface IDog { 2 | void say(String message); 3 | } 4 | -------------------------------------------------------------------------------- /examples/idogs/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | IDog mike = new Dog("mike"); 5 | IDog sten = new Dog("sten"); 6 | 7 | mike.say("hello"); 8 | sten.say("woof"); 9 | 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /examples/idogs/idogs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.loadClassFile("./IDog.class"); 7 | jvm.loadClassFile("./Dog.class"); 8 | jvm.run(); -------------------------------------------------------------------------------- /examples/idogs/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/jar/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static long fib(int n) { 4 | if (n <= 1) 5 | return n; 6 | return fib(n - 1) + fib(n - 2); 7 | } 8 | 9 | public static void main(String[] args) { 10 | if (args.length == 0) { 11 | System.out.print("help: java Fibonacci {Number}"); 12 | return; 13 | } 14 | 15 | int N = Integer.parseInt(args[0]); 16 | 17 | long start = System.currentTimeMillis(); 18 | System.out.format("Fibonacci from 1 to %s:\n", N); 19 | for (int i = 1; i <= N; i++) { 20 | System.out.println(i + ": " + fib(i)); 21 | } 22 | long stop = System.currentTimeMillis(); 23 | System.out.println("time: " + (stop - start) + "ms"); 24 | 25 | System.out.println("done."); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/jar/fibonacci.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.setLogLevel(7); 6 | var entryPointClassName = jvm.loadJarFile("./Main.jar"); 7 | jvm.setEntryPointClassName(entryPointClassName); 8 | jvm.on("exit", function(code) { 9 | process.exit(code); 10 | }); 11 | jvm.run([15]); -------------------------------------------------------------------------------- /examples/jar/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | 4 | JAR = jar 5 | JARFLAGS = cvfe 6 | 7 | .SUFFIXES: .java .class .jar 8 | 9 | .java.class: 10 | $(JC) $(JFLAGS) $*.java 11 | 12 | .class.jar: 13 | $(JAR) $(JARFLAGS) Main.jar Main *.class 14 | 15 | CLASSES = \ 16 | Main.java 17 | 18 | default: jar 19 | 20 | classes: $(CLASSES:.java=.class) 21 | 22 | jar: $(CLASSES:.java=.jar) 23 | 24 | clean: 25 | $(RM) *.class 26 | $(RM) *.jar -------------------------------------------------------------------------------- /examples/jar/manifest.txt: -------------------------------------------------------------------------------- 1 | Main-Class: Main -------------------------------------------------------------------------------- /examples/jsclass/IMyJsClass.java: -------------------------------------------------------------------------------- 1 | public interface IMyJsClass { 2 | void init(String nick); 3 | String getName(); 4 | void say(String message); 5 | void bye(); 6 | } 7 | -------------------------------------------------------------------------------- /examples/jsclass/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | 4 | public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { 5 | IMyJsClass obj = (IMyJsClass) Class.forName("jvm/examples/jsclass/MyJsClass").newInstance(); 6 | obj.init("Tom"); 7 | System.out.println("My nick is " + obj.getName()); 8 | obj.say("Hello from java to node"); 9 | obj.bye(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /examples/jsclass/MyJsClass.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var MyJsClass = module.exports = function() { 4 | if (this instanceof MyJsClass) { 5 | } else { 6 | return new MyJsClass(); 7 | } 8 | } 9 | 10 | MyJsClass.getClassName = function() { 11 | return "jvm/examples/jsclass/MyJsClass"; 12 | } 13 | 14 | MyJsClass.prototype.init = function(nick) { 15 | this.nick = nick; 16 | } 17 | 18 | MyJsClass.prototype.getName = function() { 19 | return this.nick; 20 | } 21 | 22 | MyJsClass.prototype.say = function(message) { 23 | console.log("This message from java <" + message + ">"); 24 | } 25 | 26 | MyJsClass.prototype.bye = function() { 27 | console.log(this.nick + ": bye!!!"); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /examples/jsclass/jsclass.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFiles(__dirname); 6 | jvm.loadJSFile(__dirname + "/MyJsClass.js"); 7 | jvm.run(); -------------------------------------------------------------------------------- /examples/jsclass/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/nested/Clazz.java: -------------------------------------------------------------------------------- 1 | 2 | public class Clazz { 3 | 4 | class Test { 5 | public void print(String msg) { 6 | System.out.println(msg); 7 | } 8 | } 9 | 10 | public Test test = new Test(); 11 | } -------------------------------------------------------------------------------- /examples/nested/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | 4 | 5 | public static void main(String[] args) { 6 | Clazz clazz = new Clazz(); 7 | clazz.test.print("print from nested class"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /examples/nested/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/nested/nested.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/static/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | public static void main(String[] args) { 3 | MySystem.out.println("id = " + MySystem.out.id); 4 | 5 | MyOut o = MySystem.out; 6 | o.id = "changed 1"; 7 | o.println("id = " + o.id); 8 | 9 | MySystem.out = new MyOut("changed 2"); 10 | MySystem.out.println("id = " + MySystem.out.id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/static/MyOut.java: -------------------------------------------------------------------------------- 1 | public class MyOut { 2 | public String id; 3 | 4 | public MyOut(String id) { 5 | this.id = id; 6 | } 7 | 8 | public static void println(String message) { 9 | System.out.println(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/static/MySystem.java: -------------------------------------------------------------------------------- 1 | 2 | public class MySystem { 3 | public static MyOut out = new MyOut("default"); 4 | } 5 | -------------------------------------------------------------------------------- /examples/static/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/static/static.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFiles(__dirname); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/switcher/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static int test(int i) { 4 | switch (i) { 5 | case 1: return (10); 6 | case 10: return (100); 7 | default: return (0); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | System.out.println("test: " + test(10)); 14 | 15 | for (int i = 10; i <= 13; i++) { 16 | switch (i) { 17 | case 10: 18 | System.out.println("10"); 19 | break; 20 | case 11: case 12: 21 | System.out.println("11 or 12"); 22 | break; 23 | default: 24 | System.out.println("13"); 25 | } 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/switcher/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/switcher/switcher.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFile("./Main.class"); 6 | jvm.run(); -------------------------------------------------------------------------------- /examples/threads/Dog.java: -------------------------------------------------------------------------------- 1 | class Dog implements Runnable { 2 | private Object obj; 3 | private String name; 4 | private int length; 5 | 6 | 7 | public Dog(String name, int length) { 8 | this.obj = null; 9 | this.name = name; 10 | this.length = length; 11 | } 12 | 13 | public Dog(String name, int length, Object obj) { 14 | this(name, length); 15 | this.obj = obj; 16 | } 17 | 18 | public void run() { 19 | if (obj != null) { 20 | synchronized(obj) { 21 | for (int i = 0; i < length; i++) { 22 | System.out.println("Hello from lock " + name + ": " + i); 23 | } 24 | } 25 | } else { 26 | for (int i = 0; i < length; i++) { 27 | System.out.println("Hello from non-lock " + name + ": " + i); 28 | } 29 | } 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /examples/threads/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | 4 | public static void main(String[] args) throws InterruptedException { 5 | 6 | Object locker = new Object(); 7 | 8 | Dog mike = new Dog("Mike", 10, locker); 9 | Thread mikeThread = new Thread(mike); 10 | 11 | Dog sten = new Dog("Sten", 15, locker); 12 | Thread stenThread = new Thread(sten); 13 | 14 | Dog nika = new Dog("Nika", 30); 15 | Thread nikaThread = new Thread(nika); 16 | nikaThread.setPriority(Thread.MAX_PRIORITY); 17 | 18 | mikeThread.start(); 19 | stenThread.start(); 20 | nikaThread.start(); 21 | 22 | System.out.println("Done."); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/threads/makefile: -------------------------------------------------------------------------------- 1 | JFLAGS = -g 2 | JC = javac 3 | .SUFFIXES: .java .class 4 | .java.class: 5 | $(JC) $(JFLAGS) $*.java 6 | 7 | CLASSES = \ 8 | Main.java 9 | 10 | default: classes 11 | 12 | classes: $(CLASSES:.java=.class) 13 | 14 | clean: 15 | $(RM) *.class -------------------------------------------------------------------------------- /examples/threads/threads.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var JVM = require("../../index"); 4 | var jvm = new JVM(); 5 | jvm.loadClassFiles(__dirname); 6 | jvm.run(); -------------------------------------------------------------------------------- /help.txt: -------------------------------------------------------------------------------- 1 | http://docs.oracle.com/javase/specs/jvms/se5.0/html/VMSpecTOC.doc.html 2 | http://habrahabr.ru/post/178315/ 3 | http://homepages.inf.ed.ac.uk/kwxm/JVM/codeByNo.html 4 | http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javap.html 5 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./libs/jvm.js"); -------------------------------------------------------------------------------- /libs/arraytypes.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var ARRAY_TYPE = module.exports = { 7 | T_BOOLEAN: 4, 8 | T_CHAR: 5, 9 | T_FLOAT: 6, 10 | T_DOUBLE: 7, 11 | T_BYTE: 8, 12 | T_SHORT: 9, 13 | T_INT: 10, 14 | T_LONG: 11 15 | } -------------------------------------------------------------------------------- /libs/classes.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var fs = require("fs"); 8 | var path = require("path"); 9 | 10 | var ClassArea = require("./classfile/classarea.js"); 11 | var Frame = require("./frame.js"); 12 | 13 | var ACCESS_FLAGS = require("./classfile/accessflags.js"); 14 | 15 | var Classes = module.exports = function() { 16 | if (this instanceof Classes) { 17 | this.paths = [ __dirname ]; 18 | this.classes = {}; 19 | this.staticFields = {}; 20 | } else { 21 | return new Classes(); 22 | } 23 | } 24 | 25 | Classes.prototype.addPath = function(path) { 26 | if (this.paths.indexOf(path) === -1) { 27 | this.paths.push(path); 28 | } 29 | } 30 | 31 | Classes.prototype.clinit = function() { 32 | for(var className in this.classes) { 33 | classArea = this.classes[className]; 34 | var clinit = this.getStaticMethod(className, "", "()V"); 35 | if (clinit instanceof Frame) { 36 | SCHEDULER.sync(function() { 37 | LOG.debug("call " + className + ". ..."); 38 | clinit.run([], function() { 39 | LOG.debug("call " + className + ". ... done"); 40 | }); 41 | }); 42 | } 43 | } 44 | } 45 | 46 | Classes.prototype.loadClassBytes = function(bytes) { 47 | var classArea = new ClassArea(bytes); 48 | this.classes[classArea.getClassName()] = classArea; 49 | return classArea; 50 | } 51 | 52 | Classes.prototype.loadClassFile = function(fileName) { 53 | LOG.debug("loading " + fileName + " ..."); 54 | var bytes = fs.readFileSync(fileName); 55 | var ca = this.loadClassBytes(bytes); 56 | var classes = ca.getClasses(); 57 | for (var i=0; i"](message, cause); 225 | return ex; 226 | } 227 | 228 | -------------------------------------------------------------------------------- /libs/classfile/accessflags.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var checkFlag = function(flag) { 7 | return function(flags) { 8 | return ((flags & flag) === flag); 9 | } 10 | }; 11 | 12 | var ACCESS_FLAGS = module.exports = { 13 | ACC_PUBLIC: 0x0001, 14 | ACC_PRIVATE: 0x0002, 15 | ACC_PROTECTED: 0x0004, 16 | ACC_STATIC: 0x0008, 17 | ACC_FINAL: 0x0010, 18 | ACC_SYNCHRONIZED: 0x0020, 19 | ACC_VOLATILE: 0x0040, 20 | ACC_TRANSIENT: 0x0080, 21 | ACC_NATIVE: 0x0100, 22 | ACC_INTERFACE: 0x0200, 23 | ACC_ABSTRACT: 0x0400, 24 | toString: function(flags) { 25 | var flagNames = []; 26 | for(var flag in this) { 27 | if ((this[flag] & flags) === this[flag]) { 28 | flagNames.push(flag); 29 | } 30 | } 31 | return flagNames.toString(); 32 | }, 33 | isPublic: function(flags) { return checkFlag(this.ACC_PUBLIC)(flags) }, 34 | isPrivate: function(flags) { return checkFlag(this.ACC_PRIVATE)(flags) }, 35 | isProtected: function(flags) { return checkFlag(this.ACC_PROTECTED)(flags) }, 36 | isStatic: function(flags) { return checkFlag(this.ACC_STATIC)(flags) }, 37 | isFinal: function(flags) { return checkFlag(this.ACC_FINAL)(flags) }, 38 | isSynchronized: function(flags) { return checkFlag(this.ACC_SYNCHRONIZED)(flags) }, 39 | isVolatile: function(flags) { return checkFlag(this.ACC_VOLATILE)(flags) }, 40 | isTransient: function(flags) { return checkFlag(this.ACC_TRANSIENT)(flags) }, 41 | isNative: function(flags) { return checkFlag(this.ACC_NATIVE)(flags) }, 42 | isInterface: function(flags) { return checkFlag(this.ACC_INTERFACE)(flags) }, 43 | isAbstract: function(flags) { return checkFlag(this.ACC_ABSTRACT)(flags) } 44 | }; 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /libs/classfile/attributetypes.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var ATTRIBUTE_TYPES = module.exports = { 7 | ConstantValue: "ConstantValue", 8 | Code: "Code", 9 | Exceptions: "Exceptions", 10 | InnerClasses: "InnerClasses", 11 | Synthetic: "Synthetic", 12 | SourceFile: "SourceFile", 13 | LineNumberTable: "LineNumberTable", 14 | LocalVariableTable: "LocalVariableTable", 15 | Deprecated: "Deprecated" 16 | }; 17 | -------------------------------------------------------------------------------- /libs/classfile/classarea.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"), 7 | Reader = require("../util/reader.js"), 8 | TAGS = require("./tags.js"), 9 | ACCESS_FLAGS = require("./accessflags.js"), 10 | ATTRIBUTE_TYPES = require("./attributetypes.js"); 11 | 12 | 13 | var ClassArea = module.exports = function(classBytes) { 14 | if (this instanceof ClassArea) { 15 | this.classImage = getClassImage(classBytes); 16 | } else { 17 | return new ClassArea(classBytes); 18 | } 19 | } 20 | 21 | ClassArea.prototype.getClassName = function() { 22 | return this.classImage.constant_pool[this.classImage.constant_pool[this.classImage.this_class].name_index].bytes; 23 | } 24 | 25 | ClassArea.prototype.getSuperClassName = function() { 26 | return this.classImage.constant_pool[this.classImage.constant_pool[this.classImage.super_class].name_index].bytes; 27 | } 28 | 29 | ClassArea.prototype.getAccessFlags = function() { 30 | return this.classImage.access_flags; 31 | } 32 | 33 | ClassArea.prototype.getConstantPool = function() { 34 | return this.classImage.constant_pool; 35 | } 36 | 37 | ClassArea.prototype.getFields = function() { 38 | return this.classImage.fields; 39 | } 40 | 41 | ClassArea.prototype.getMethods = function() { 42 | return this.classImage.methods; 43 | } 44 | 45 | ClassArea.prototype.getClasses = function() { 46 | var self = this; 47 | var classes = []; 48 | this.classImage.attributes.forEach(function(a) { 49 | if (a.info.type === ATTRIBUTE_TYPES.InnerClasses) { 50 | a.info.classes.forEach(function(c) { 51 | classes.push(self.classImage.constant_pool[self.classImage.constant_pool[c.inner_class_info_index].name_index].bytes); 52 | classes.push(self.classImage.constant_pool[self.classImage.constant_pool[c.outer_class_info_index].name_index].bytes); 53 | }); 54 | } 55 | }); 56 | return classes; 57 | } 58 | 59 | var getClassImage = function(classBytes) { 60 | 61 | var classImage = {}; 62 | 63 | var getAttributes = function(attribute_name_index, bytes) { 64 | 65 | var reader = new Reader.create(bytes); 66 | var attribute = { attribute_name_index: attribute_name_index }; 67 | 68 | 69 | var item = classImage.constant_pool[attribute_name_index]; 70 | 71 | 72 | switch(item.tag) { 73 | 74 | case TAGS.CONSTANT_Long: 75 | case TAGS.CONSTANT_Float: 76 | case TAGS.CONSTANT_Double: 77 | case TAGS.CONSTANT_Integer: 78 | case TAGS.CONSTANT_String: 79 | attribute.type = ATTRIBUTE_TYPES.ConstantValue; 80 | attribute.constantvalue_index = reader.read16(); 81 | return attribute; 82 | 83 | 84 | case TAGS.CONSTANT_Utf8: 85 | 86 | switch(item.bytes) { 87 | 88 | case ATTRIBUTE_TYPES.Code: 89 | attribute.type = ATTRIBUTE_TYPES.Code; 90 | attribute.max_stack = reader.read16(); 91 | attribute.max_locals = reader.read16(); 92 | var code_length = reader.read32(); 93 | attribute.code = reader.readBytes(code_length); 94 | 95 | var exception_table_length = reader.read16(); 96 | attribute.exception_table = []; 97 | for(var i=0; i 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var TYPE = module.exports.TYPE = { 9 | boolean: 'Z', 10 | byte: 'B', 11 | char: 'C', 12 | double: 'D', 13 | float: 'F', 14 | int: 'I', 15 | long: 'J', 16 | object: 'L', 17 | short: 'S', 18 | void: 'V', 19 | array: '[', 20 | toString: function(s) { 21 | for(var type in this) { 22 | if (this[type] === s) { 23 | return type; 24 | } 25 | } 26 | return null; 27 | } 28 | }; 29 | 30 | 31 | var _parse = function(part) { 32 | var res = []; 33 | if (part != '') { 34 | var isArray = false; 35 | var pos = 0; 36 | while (pos < part.length) { 37 | switch(part[pos]) { 38 | case TYPE.boolean: 39 | case TYPE.byte: 40 | case TYPE.char: 41 | case TYPE.double: 42 | case TYPE.float: 43 | case TYPE.int: 44 | case TYPE.long: 45 | case TYPE.short: 46 | res.push( { type: TYPE.toString(part[pos]), isArray: isArray } ); 47 | isArray = false; 48 | break; 49 | case TYPE.object: 50 | var className = ''; 51 | while (part[++pos] !== ';') { 52 | className += part[pos]; 53 | } 54 | res.push( { type: "object", isArray: isArray, className: className } ); 55 | isArray = false; 56 | break; 57 | case TYPE.array: 58 | isArray = true; 59 | break; 60 | } 61 | pos++; 62 | } 63 | } 64 | return res; 65 | } 66 | 67 | var parse = module.exports.parse = function(s) { 68 | 69 | var IN = s.split(')')[0].substr(1); 70 | var OUT = s.split(')')[1]; 71 | 72 | return { 73 | IN: _parse(IN), 74 | OUT: _parse(OUT), 75 | toString: new Function(util.format("return \"%s\"", s)) 76 | }; 77 | }; 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /libs/classfile/tags.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | 7 | var TAGS = module.exports = { 8 | CONSTANT_Class: 7, 9 | CONSTANT_Fieldref: 9, 10 | CONSTANT_Methodref: 10, 11 | CONSTANT_InterfaceMethodref: 11, 12 | CONSTANT_String: 8, 13 | CONSTANT_Integer: 3, 14 | CONSTANT_Float: 4, 15 | CONSTANT_Long: 5, 16 | CONSTANT_Double: 6, 17 | CONSTANT_NameAndType: 12, 18 | CONSTANT_Utf8: 1, 19 | CONSTANT_Unicode: 2, 20 | toString: function(tag) { 21 | for(var name in this) { 22 | if (this[name] === tag) { 23 | return name; 24 | } 25 | } 26 | return null; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /libs/frame.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var Numeric = require("./util/numeric"); 9 | var Signature = require("./classfile/signature"); 10 | 11 | var TAGS = require("./classfile/tags"); 12 | var ATTRIBUTE_TYPES = require("./classfile/attributetypes"); 13 | 14 | var Frame = module.exports = function(classArea, method) { 15 | if (this instanceof Frame) { 16 | this._pid = 0; // default main thread 17 | this._cp = classArea.getConstantPool(); 18 | 19 | for(var i=0; i= this._exception_table[i].start_pc && this._ip <= this._exception_table[i].end_pc) { 54 | if (this._exception_table[i].catch_type === 0) { 55 | handler_pc = this._exception_table[i].handler_pc; 56 | } else { 57 | var name = this._cp[this._cp[this._exception_table[i].catch_type].name_index].bytes; 58 | if (name === ex.getClassName()) { 59 | handler_pc = this._exception_table[i].handler_pc; 60 | break; 61 | } 62 | } 63 | } 64 | } 65 | 66 | if (handler_pc != null) { 67 | this._stack.push(ex); 68 | this._ip = handler_pc; 69 | } else { 70 | throw ex; 71 | } 72 | } 73 | 74 | Frame.prototype.run = function(args, done) { 75 | var self = this; 76 | 77 | this._ip = 0; 78 | this._stack = []; 79 | this._widened = false; 80 | 81 | for(var i=0; i= refArray.length) { 419 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 420 | } 421 | 422 | if (ex) { 423 | this._throw(ex); 424 | } else { 425 | this._stack.push(refArray[idx]); 426 | } 427 | 428 | return done(); 429 | } 430 | 431 | Frame.prototype.laload = function(done) { 432 | var idx = this._stack.pop(); 433 | var refArray = this._stack.pop(); 434 | 435 | var ex = null; 436 | 437 | if (!refArray) { 438 | ex = CLASSES.newException("java/lang/NullPointerException"); 439 | } else if (idx < 0 || idx >= refArray.length) { 440 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 441 | } 442 | 443 | if (ex) { 444 | this._throw(ex); 445 | } else { 446 | this._stack.push(refArray[idx]); 447 | } 448 | 449 | return done(); 450 | } 451 | 452 | Frame.prototype.faload = function(done) { 453 | var idx = this._stack.pop(); 454 | var refArray = this._stack.pop(); 455 | 456 | var ex = null; 457 | 458 | if (!refArray) { 459 | ex = CLASSES.newException("java/lang/NullPointerException"); 460 | } else if (idx < 0 || idx >= refArray.length) { 461 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 462 | } 463 | 464 | if (ex) { 465 | this._throw(ex); 466 | } else { 467 | this._stack.push(refArray[idx]); 468 | } 469 | 470 | return done(); 471 | } 472 | 473 | 474 | Frame.prototype.daload = function(done) { 475 | var idx = this._stack.pop(); 476 | var refArray = this._stack.pop(); 477 | 478 | var ex = null; 479 | 480 | if (!refArray) { 481 | ex = CLASSES.newException("java/lang/NullPointerException"); 482 | } else if (idx < 0 || idx >= refArray.length) { 483 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 484 | } 485 | 486 | if (ex) { 487 | this._throw(ex); 488 | } else { 489 | this._stack.push(refArray[idx]); 490 | } 491 | 492 | return done(); 493 | } 494 | 495 | Frame.prototype.aaload = function(done) { 496 | var idx = this._stack.pop(); 497 | var refArray = this._stack.pop(); 498 | 499 | var ex = null; 500 | 501 | if (!refArray) { 502 | ex = CLASSES.newException("java/lang/NullPointerException"); 503 | } else if (idx < 0 || idx >= refArray.length) { 504 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 505 | } 506 | 507 | if (ex) { 508 | this._throw(ex); 509 | } else { 510 | this._stack.push(refArray[idx]); 511 | } 512 | 513 | return done(); 514 | } 515 | 516 | Frame.prototype.baload = function(done) { 517 | var idx = this._stack.pop(); 518 | var refArray = this._stack.pop(); 519 | 520 | var ex = null; 521 | 522 | if (!refArray) { 523 | ex = CLASSES.newException("java/lang/NullPointerException"); 524 | } else if (idx < 0 || idx >= refArray.length) { 525 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 526 | } 527 | 528 | if (ex) { 529 | this._throw(ex); 530 | } else { 531 | this._stack.push(refArray[idx]); 532 | } 533 | 534 | return done(); 535 | } 536 | 537 | Frame.prototype.caload = function(done) { 538 | var idx = this._stack.pop(); 539 | var refArray = this._stack.pop(); 540 | 541 | var ex = null; 542 | 543 | if (!refArray) { 544 | ex = CLASSES.newException("java/lang/NullPointerException"); 545 | } else if (idx < 0 || idx >= refArray.length) { 546 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 547 | } 548 | 549 | if (ex) { 550 | this._throw(ex); 551 | } else { 552 | this._stack.push(refArray[idx]); 553 | } 554 | 555 | return done(); 556 | } 557 | 558 | Frame.prototype.saload = function(done) { 559 | var idx = this._stack.pop(); 560 | var refArray = this._stack.pop(); 561 | 562 | var ex = null; 563 | 564 | if (!refArray) { 565 | ex = CLASSES.newException("java/lang/NullPointerException"); 566 | } else if (idx < 0 || idx >= refArray.length) { 567 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 568 | } 569 | 570 | if (ex) { 571 | this._throw(ex); 572 | } else { 573 | this._stack.push(refArray[idx]); 574 | } 575 | 576 | return done(); 577 | } 578 | 579 | Frame.prototype.istore = function(done) { 580 | var idx = this._widened ? this._read16() : this._read8(); 581 | this._locals[idx] = this._stack.pop(); 582 | this._widened = false; 583 | return done(); 584 | } 585 | 586 | Frame.prototype.lstore = function(done) { 587 | var idx = this._widened ? this._read16() : this._read8(); 588 | this._locals[idx] = this._stack.pop(); 589 | this._widened = false; 590 | return done(); 591 | } 592 | 593 | Frame.prototype.fstore = function(done) { 594 | var idx = this._widened ? this._read16() : this._read8(); 595 | this._locals[idx] = this._stack.pop(); 596 | this._widened = false; 597 | return done(); 598 | } 599 | 600 | Frame.prototype.dstore = function(done) { 601 | var idx = this._widened ? this._read16() : this._read8(); 602 | this._locals[idx] = this._stack.pop(); 603 | this._widened = false; 604 | return done(); 605 | } 606 | 607 | Frame.prototype.astore = function(done) { 608 | var idx = this._widened ? this._read16() : this._read8(); 609 | this._locals[idx] = this._stack.pop(); 610 | this._widened = false; 611 | return done(); 612 | } 613 | 614 | Frame.prototype.istore_0 = function(done) { 615 | this._locals[0] = this._stack.pop(); 616 | return done(); 617 | } 618 | 619 | Frame.prototype.lstore_0 = function(done) { 620 | this._locals[0] = this._stack.pop(); 621 | return done(); 622 | } 623 | 624 | Frame.prototype.fstore_0 = function(done) { 625 | this._locals[0] = this._stack.pop(); 626 | return done(); 627 | } 628 | 629 | Frame.prototype.dstore_0 = function(done) { 630 | this._locals[0] = this._stack.pop(); 631 | return done(); 632 | } 633 | 634 | Frame.prototype.astore_0 = function(done) { 635 | this._locals[0] = this._stack.pop(); 636 | return done(); 637 | } 638 | 639 | Frame.prototype.istore_1 = function(done) { 640 | this._locals[1] = this._stack.pop(); 641 | return done(); 642 | } 643 | 644 | Frame.prototype.lstore_1 = function(done) { 645 | this._locals[1] = this._stack.pop(); 646 | return done(); 647 | } 648 | 649 | Frame.prototype.fstore_1 = function(done) { 650 | this._locals[1] = this._stack.pop(); 651 | return done(); 652 | } 653 | 654 | Frame.prototype.dstore_1 = function(done) { 655 | this._locals[1] = this._stack.pop(); 656 | return done(); 657 | } 658 | 659 | Frame.prototype.astore_1 = function(done) { 660 | this._locals[1] = this._stack.pop(); 661 | return done(); 662 | } 663 | 664 | 665 | Frame.prototype.istore_2 = function(done) { 666 | this._locals[2] = this._stack.pop(); 667 | return done(); 668 | } 669 | 670 | Frame.prototype.lstore_2 = function(done) { 671 | this._locals[2] = this._stack.pop(); 672 | return done(); 673 | } 674 | 675 | Frame.prototype.fstore_2 = function(done) { 676 | this._locals[2] = this._stack.pop(); 677 | return done(); 678 | } 679 | 680 | Frame.prototype.dstore_2 = function(done) { 681 | this._locals[2] = this._stack.pop(); 682 | return done(); 683 | } 684 | 685 | Frame.prototype.astore_2 = function(done) { 686 | this._locals[2] = this._stack.pop(); 687 | return done(); 688 | } 689 | 690 | Frame.prototype.istore_3 = function(done) { 691 | this._locals[3] = this._stack.pop(); 692 | return done(); 693 | } 694 | 695 | Frame.prototype.lstore_3 = function(done) { 696 | this._locals[3] = this._stack.pop(); 697 | return done(); 698 | } 699 | 700 | Frame.prototype.fstore_3 = function(done) { 701 | this._locals[3] = this._stack.pop(); 702 | return done(); 703 | } 704 | 705 | Frame.prototype.dstore_3 = function(done) { 706 | this._locals[3] = this._stack.pop(); 707 | return done(); 708 | } 709 | 710 | Frame.prototype.astore_3 = function(done) { 711 | this._locals[3] = this._stack.pop(); 712 | return done(); 713 | } 714 | 715 | Frame.prototype.iastore = function(done) { 716 | var val = this._stack.pop(); 717 | var idx = this._stack.pop(); 718 | var refArray = this._stack.pop(); 719 | 720 | 721 | var ex = null; 722 | 723 | if (!refArray) { 724 | ex = CLASSES.newException("java/lang/NullPointerException"); 725 | } else if (idx < 0 || idx >= refArray.length) { 726 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 727 | } 728 | 729 | if (ex) { 730 | this._throw(ex); 731 | } else { 732 | refArray[idx] = val; 733 | } 734 | 735 | return done(); 736 | } 737 | 738 | Frame.prototype.lastore = function(done) { 739 | var val = this._stack.pop(); 740 | var idx = this._stack.pop(); 741 | var refArray = this._stack.pop(); 742 | 743 | 744 | var ex = null; 745 | 746 | if (!refArray) { 747 | ex = CLASSES.newException("java/lang/NullPointerException"); 748 | } else if (idx < 0 || idx >= refArray.length) { 749 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 750 | } 751 | 752 | if (ex) { 753 | this._throw(ex); 754 | } else { 755 | refArray[idx] = val; 756 | } 757 | 758 | return done(); 759 | } 760 | 761 | Frame.prototype.fastore = function(done) { 762 | var val = this._stack.pop(); 763 | var idx = this._stack.pop(); 764 | var refArray = this._stack.pop(); 765 | 766 | 767 | var ex = null; 768 | 769 | if (!refArray) { 770 | ex = CLASSES.newException("java/lang/NullPointerException"); 771 | } else if (idx < 0 || idx >= refArray.length) { 772 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 773 | } 774 | 775 | if (ex) { 776 | this._throw(ex); 777 | } else { 778 | refArray[idx] = val; 779 | } 780 | 781 | return done(); 782 | } 783 | 784 | Frame.prototype.dastore = function(done) { 785 | var val = this._stack.pop(); 786 | var idx = this._stack.pop(); 787 | var refArray = this._stack.pop(); 788 | 789 | 790 | var ex = null; 791 | 792 | if (!refArray) { 793 | ex = CLASSES.newException("java/lang/NullPointerException"); 794 | } else if (idx < 0 || idx >= refArray.length) { 795 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 796 | } 797 | 798 | if (ex) { 799 | this._throw(ex); 800 | } else { 801 | refArray[idx] = val; 802 | } 803 | 804 | return done(); 805 | } 806 | 807 | Frame.prototype.aastore = function(done) { 808 | var val = this._stack.pop(); 809 | var idx = this._stack.pop(); 810 | var refArray = this._stack.pop(); 811 | 812 | 813 | var ex = null; 814 | 815 | if (!refArray) { 816 | ex = CLASSES.newException("java/lang/NullPointerException"); 817 | } else if (idx < 0 || idx >= refArray.length) { 818 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 819 | } 820 | 821 | if (ex) { 822 | this._throw(ex); 823 | } else { 824 | refArray[idx] = val; 825 | } 826 | 827 | return done(); 828 | } 829 | 830 | Frame.prototype.bastore = function(done) { 831 | var val = this._stack.pop(); 832 | var idx = this._stack.pop(); 833 | var refArray = this._stack.pop(); 834 | 835 | 836 | var ex = null; 837 | 838 | if (!refArray) { 839 | ex = CLASSES.newException("java/lang/NullPointerException"); 840 | } else if (idx < 0 || idx >= refArray.length) { 841 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 842 | } 843 | 844 | if (ex) { 845 | this._throw(ex); 846 | } else { 847 | refArray[idx] = val; 848 | } 849 | 850 | return done(); 851 | } 852 | 853 | Frame.prototype.castore = function(done) { 854 | var val = this._stack.pop(); 855 | var idx = this._stack.pop(); 856 | var refArray = this._stack.pop(); 857 | 858 | 859 | var ex = null; 860 | 861 | if (!refArray) { 862 | ex = CLASSES.newException("java/lang/NullPointerException"); 863 | } else if (idx < 0 || idx >= refArray.length) { 864 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 865 | } 866 | 867 | if (ex) { 868 | this._throw(ex); 869 | } else { 870 | refArray[idx] = val; 871 | } 872 | 873 | return done(); 874 | } 875 | 876 | Frame.prototype.sastore = function(done) { 877 | var val = this._stack.pop(); 878 | var idx = this._stack.pop(); 879 | var refArray = this._stack.pop(); 880 | 881 | 882 | var ex = null; 883 | 884 | if (!refArray) { 885 | ex = CLASSES.newException("java/lang/NullPointerException"); 886 | } else if (idx < 0 || idx >= refArray.length) { 887 | ex = CLASSES.newException("java/lang/ArrayIndexOutOfBoundsException", idx); 888 | } 889 | 890 | if (ex) { 891 | this._throw(ex); 892 | } else { 893 | refArray[idx] = val; 894 | } 895 | 896 | return done(); 897 | } 898 | 899 | Frame.prototype.pop = function(done) { 900 | this._stack.pop(); 901 | return done(); 902 | } 903 | 904 | Frame.prototype.pop2 = function(done) { 905 | this._stack.pop(); 906 | return done(); 907 | } 908 | 909 | Frame.prototype.dup = function(done) { 910 | var val = this._stack.pop(); 911 | this._stack.push(val); 912 | this._stack.push(val); 913 | return done(); 914 | } 915 | 916 | Frame.prototype.dup_x1 = function(done) { 917 | var val1 = this._stack.pop(); 918 | var val2 = this._stack.pop(); 919 | this._stack.push(val1); 920 | this._stack.push(val2); 921 | this._stack.push(val1); 922 | return done(); 923 | } 924 | 925 | Frame.prototype.dup_x2 = function(done) { 926 | var val1 = this._stack.pop(); 927 | var val2 = this._stack.pop(); 928 | var val3 = this._stack.pop(); 929 | this._stack.push(val1); 930 | this._stack.push(val3); 931 | this._stack.push(val2); 932 | this._stack.push(val1); 933 | return done(); 934 | } 935 | 936 | Frame.prototype.dup2 = function(done) { 937 | var val1 = this._stack.pop(); 938 | var val2 = this._stack.pop(); 939 | this._stack.push(val2); 940 | this._stack.push(val1); 941 | this._stack.push(val2); 942 | this._stack.push(val1); 943 | return done(); 944 | } 945 | 946 | Frame.prototype.dup2_x1 = function(done) { 947 | var val1 = this._stack.pop(); 948 | var val2 = this._stack.pop(); 949 | var val3 = this._stack.pop(); 950 | this._stack.push(val2); 951 | this._stack.push(val1); 952 | this._stack.push(val3); 953 | this._stack.push(val2); 954 | this._stack.push(val1); 955 | return done(); 956 | } 957 | 958 | Frame.prototype.dup2_x2 = function(done) { 959 | var val1 = this._stack.pop(); 960 | var val2 = this._stack.pop(); 961 | var val3 = this._stack.pop(); 962 | var val4 = this._stack.pop(); 963 | this._stack.push(val2); 964 | this._stack.push(val1); 965 | this._stack.push(val4); 966 | this._stack.push(val3); 967 | this._stack.push(val2); 968 | this._stack.push(val1); 969 | return done(); 970 | } 971 | 972 | 973 | Frame.prototype.swap = function(done) { 974 | var val1 = this._stack.pop(); 975 | var val2 = this._stack.pop(); 976 | this._stack.push(val1); 977 | this._stack.push(val2); 978 | return done(); 979 | } 980 | 981 | 982 | Frame.prototype.iinc = function(done) { 983 | var idx = this._widened ? this._read16() : this._read8(); 984 | var val = this._widened ? this._read16() : this._read8(); 985 | this._locals[idx] += val 986 | this._widened = false; 987 | return done(); 988 | } 989 | 990 | Frame.prototype.iadd = function(done) { 991 | this._stack.push(this._stack.pop() + this._stack.pop()); 992 | return done(); 993 | } 994 | 995 | Frame.prototype.ladd = function(done) { 996 | this._stack.push(this._stack.pop() + this._stack.pop()); 997 | return done(); 998 | } 999 | 1000 | Frame.prototype.dadd = function(done) { 1001 | this._stack.push(this._stack.pop() + this._stack.pop()); 1002 | return done(); 1003 | } 1004 | 1005 | Frame.prototype.fadd = function(done) { 1006 | this._stack.push(this._stack.pop() + this._stack.pop()); 1007 | return done(); 1008 | } 1009 | 1010 | Frame.prototype.isub = function(done) { 1011 | this._stack.push(- this._stack.pop() + this._stack.pop()); 1012 | return done(); 1013 | } 1014 | 1015 | Frame.prototype.lsub = function(done) { 1016 | this._stack.push(- this._stack.pop() + this._stack.pop()); 1017 | return done(); 1018 | } 1019 | 1020 | Frame.prototype.dsub = function(done) { 1021 | this._stack.push(- this._stack.pop() + this._stack.pop()); 1022 | return done(); 1023 | } 1024 | 1025 | Frame.prototype.fsub = function(done) { 1026 | this._stack.push(- this._stack.pop() + this._stack.pop()); 1027 | return done(); 1028 | } 1029 | 1030 | Frame.prototype.imul = function(done) { 1031 | this._stack.push(this._stack.pop() * this._stack.pop()); 1032 | return done(); 1033 | } 1034 | 1035 | Frame.prototype.lmul = function(done) { 1036 | this._stack.push(this._stack.pop() * this._stack.pop()); 1037 | return done(); 1038 | } 1039 | 1040 | Frame.prototype.dmul = function(done) { 1041 | this._stack.push(this._stack.pop() * this._stack.pop()); 1042 | return done(); 1043 | } 1044 | 1045 | Frame.prototype.fmul = function(done) { 1046 | this._stack.push(this._stack.pop() * this._stack.pop()); 1047 | return done(); 1048 | } 1049 | 1050 | Frame.prototype.idiv = function(done) { 1051 | var val1 = this._stack.pop(); 1052 | var val2 = this._stack.pop(); 1053 | if (val1 === 0) { 1054 | this._throw(CLASSES.newException("java/lang/ArithmeticException")); 1055 | } else { 1056 | this._stack.push(val2 / val1); 1057 | } 1058 | return done(); 1059 | } 1060 | 1061 | Frame.prototype.ldiv = function(done) { 1062 | var val1 = this._stack.pop(); 1063 | var val2 = this._stack.pop(); 1064 | if (val1 === 0) { 1065 | this._throw(CLASSES.newException("java/lang/ArithmeticException")); 1066 | } else { 1067 | this._stack.push(val2 / val1); 1068 | } 1069 | return done(); 1070 | } 1071 | 1072 | Frame.prototype.ddiv = function(done) { 1073 | var val1 = this._stack.pop(); 1074 | var val2 = this._stack.pop(); 1075 | this._stack.push(val2 / val1); 1076 | return done(); 1077 | } 1078 | 1079 | Frame.prototype.fdiv = function(done) { 1080 | var val1 = this._stack.pop(); 1081 | var val2 = this._stack.pop(); 1082 | this._stack.push(val2 / val1); 1083 | return done(); 1084 | } 1085 | 1086 | Frame.prototype.irem = function(done) { 1087 | var val1 = this._stack.pop(); 1088 | var val2 = this._stack.pop(); 1089 | this._stack.push(val2 % val1); 1090 | return done(); 1091 | } 1092 | 1093 | Frame.prototype.lrem = function(done) { 1094 | var val1 = this._stack.pop(); 1095 | var val2 = this._stack.pop(); 1096 | this._stack.push(val2 % val1); 1097 | return done(); 1098 | } 1099 | 1100 | Frame.prototype.drem = function(done) { 1101 | var val1 = this._stack.pop(); 1102 | var val2 = this._stack.pop(); 1103 | this._stack.push(val2 % val1); 1104 | return done(); 1105 | } 1106 | 1107 | Frame.prototype.frem = function(done) { 1108 | var val1 = this._stack.pop(); 1109 | var val2 = this._stack.pop(); 1110 | this._stack.push(val2 % val1); 1111 | return done(); 1112 | } 1113 | 1114 | Frame.prototype.ineg = function(done) { 1115 | this._stack.push(- this._stack.pop()); 1116 | return done(); 1117 | } 1118 | 1119 | Frame.prototype.lneg = function(done) { 1120 | this._stack.push(- this._stack.pop()); 1121 | return done(); 1122 | } 1123 | 1124 | Frame.prototype.dneg = function(done) { 1125 | this._stack.push(- this._stack.pop()); 1126 | return done(); 1127 | } 1128 | 1129 | Frame.prototype.fneg = function(done) { 1130 | this._stack.push(- this._stack.pop()); 1131 | return done(); 1132 | } 1133 | 1134 | Frame.prototype.ishl = function(done) { 1135 | var val1 = this._stack.pop(); 1136 | var val2 = this._stack.pop(); 1137 | this._stack.push(val2 << val1); 1138 | return done(); 1139 | } 1140 | 1141 | Frame.prototype.lshl = function(done) { 1142 | var val1 = this._stack.pop(); 1143 | var val2 = this._stack.pop(); 1144 | this._stack.push(val2 << val1); 1145 | return done(); 1146 | } 1147 | 1148 | Frame.prototype.ishr = function(done) { 1149 | var val1 = this._stack.pop(); 1150 | var val2 = this._stack.pop(); 1151 | this._stack.push(val2 >> val1); 1152 | return done(); 1153 | } 1154 | 1155 | Frame.prototype.lshr = function(done) { 1156 | var val1 = this._stack.pop(); 1157 | var val2 = this._stack.pop(); 1158 | this._stack.push(val2 >> val1); 1159 | return done(); 1160 | } 1161 | 1162 | Frame.prototype.iushr = function(done) { 1163 | var val1 = this._stack.pop(); 1164 | var val2 = this._stack.pop(); 1165 | this._stack.push(val2 >>> val1); 1166 | return done(); 1167 | } 1168 | 1169 | Frame.prototype.lushr = function(done) { 1170 | var val1 = this._stack.pop(); 1171 | var val2 = this._stack.pop(); 1172 | this._stack.push(val2 >>> val1); 1173 | return done(); 1174 | } 1175 | 1176 | Frame.prototype.iand = function(done) { 1177 | this._stack.push(this._stack.pop() & this._stack.pop()); 1178 | return done(); 1179 | } 1180 | 1181 | Frame.prototype.land = function(done) { 1182 | this._stack.push(this._stack.pop() & this._stack.pop()); 1183 | return done(); 1184 | } 1185 | 1186 | Frame.prototype.ior = function(done) { 1187 | this._stack.push(this._stack.pop() | this._stack.pop()); 1188 | return done(); 1189 | } 1190 | 1191 | Frame.prototype.lor = function(done) { 1192 | this._stack.push(this._stack.pop() | this._stack.pop()); 1193 | return done(); 1194 | } 1195 | 1196 | Frame.prototype.ixor = function(done) { 1197 | this._stack.push(this._stack.pop() ^ this._stack.pop()); 1198 | return done(); 1199 | } 1200 | 1201 | Frame.prototype.lxor = function(done) { 1202 | this._stack.push(this._stack.pop() ^ this._stack.pop()); 1203 | return done(); 1204 | } 1205 | 1206 | Frame.prototype.lcmp = function(done) { 1207 | var val1 = this._stack.pop(); 1208 | var val2 = this._stack.pop(); 1209 | if (val2 > val1) { 1210 | this._stack.push(1); 1211 | } else if (val2 < val1) { 1212 | this._stack.push(-1); 1213 | } else { 1214 | this._stack.push(0); 1215 | } 1216 | return done(); 1217 | } 1218 | 1219 | Frame.prototype.fcmpl = function(done) { 1220 | var val1 = this._stack.pop(); 1221 | var val2 = this._stack.pop(); 1222 | if (isNaN(val1) || isNaN(val2)) { 1223 | this._stack.push(-1); 1224 | } else if (val2 > val1) { 1225 | this._stack.push(1); 1226 | } else if (val2 < val1) { 1227 | this._stack.push(-1); 1228 | } else { 1229 | this._stack.push(0); 1230 | } 1231 | return done; 1232 | } 1233 | 1234 | Frame.prototype.fcmpg = function(done) { 1235 | var val1 = this._stack.pop(); 1236 | var val2 = this._stack.pop(); 1237 | if (isNaN(val1) || isNaN(val2)) { 1238 | this._stack.push(1); 1239 | } else if (val2 > val1) { 1240 | this._stack.push(1); 1241 | } else if (val2 < val1) { 1242 | this._stack.push(-1); 1243 | } else { 1244 | this._stack.push(0); 1245 | } 1246 | return done; 1247 | } 1248 | 1249 | Frame.prototype.dcmpl = function(done) { 1250 | var val1 = this._stack.pop(); 1251 | var val2 = this._stack.pop(); 1252 | if (isNaN(val1) || isNaN(val2)) { 1253 | this._stack.push(-1); 1254 | } else if (val2 > val1) { 1255 | this._stack.push(1); 1256 | } else if (val2 < val1) { 1257 | this._stack.push(-1); 1258 | } else { 1259 | this._stack.push(0); 1260 | } 1261 | return done; 1262 | } 1263 | 1264 | Frame.prototype.dcmpg = function(done) { 1265 | var val1 = this._stack.pop(); 1266 | var val2 = this._stack.pop(); 1267 | if (isNaN(val1) || isNaN(val2)) { 1268 | this._stack.push(1); 1269 | } else if (val2 > val1) { 1270 | this._stack.push(1); 1271 | } else if (val2 < val1) { 1272 | this._stack.push(-1); 1273 | } else { 1274 | this._stack.push(0); 1275 | } 1276 | return done; 1277 | } 1278 | 1279 | 1280 | Frame.prototype.newarray = function(done) { 1281 | var type = this._read8(); 1282 | var size = this._stack.pop(); 1283 | if (size < 0) { 1284 | this._throw(CLASSES.newException("java/lang/NegativeSizeException")); 1285 | } else { 1286 | this._stack.push(new Array(size)); 1287 | } 1288 | return done(); 1289 | } 1290 | 1291 | 1292 | Frame.prototype.anewarray = function(done) { 1293 | var idx = this._read16(); 1294 | var className = this._cp[this._cp[idx].name_index].bytes; 1295 | var size = this._stack.pop(); 1296 | if (size < 0) { 1297 | this._throw(CLASSES.newException("java/lang/NegativeSizeException")); 1298 | } else { 1299 | this._stack.push(new Array(size)); 1300 | } 1301 | return done(); 1302 | } 1303 | 1304 | Frame.prototype.multianewarray = function(done) { 1305 | var idx = this._read16(); 1306 | var type = this._cp[this._cp[idx].name_index].bytes; 1307 | var dimensions = this._read8(); 1308 | var lengths = new Array(dimensions); 1309 | for(var i=0; i= this._stack.pop() ? jmp : this._ip; 1360 | return done(); 1361 | } 1362 | 1363 | Frame.prototype.if_icmplt = function(done) { 1364 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1365 | this._ip = this._stack.pop() > this._stack.pop() ? jmp : this._ip; 1366 | return done(); 1367 | } 1368 | 1369 | Frame.prototype.if_icmpge = function(done) { 1370 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1371 | var ref1 = this._stack.pop(); 1372 | var ref2 = this._stack.pop(); 1373 | this._ip = ref1 <= ref2 ? jmp : this._ip; 1374 | return done(); 1375 | } 1376 | 1377 | Frame.prototype.if_acmpeq = function(done) { 1378 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1379 | var ref1 = this._stack.pop(); 1380 | var ref2 = this._stack.pop(); 1381 | this._ip = ref1 === ref2 ? jmp : this._ip; 1382 | return done(); 1383 | } 1384 | 1385 | Frame.prototype.if_acmpne = function(done) { 1386 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1387 | var ref1 = this._stack.pop(); 1388 | var ref2 = this._stack.pop(); 1389 | this._ip = ref1 !== ref2 ? jmp : this._ip; 1390 | return done(); 1391 | } 1392 | 1393 | Frame.prototype.ifne = function(done) { 1394 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1395 | this._ip = this._stack.pop() !== 0 ? jmp : this._ip; 1396 | return done(); 1397 | } 1398 | 1399 | Frame.prototype.ifeq = function(done) { 1400 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1401 | this._ip = this._stack.pop() === 0 ? jmp : this._ip; 1402 | return done(); 1403 | } 1404 | 1405 | Frame.prototype.iflt = function(done) { 1406 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1407 | this._ip = this._stack.pop() < 0 ? jmp : this._ip; 1408 | return done(); 1409 | } 1410 | 1411 | Frame.prototype.ifge = function(done) { 1412 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1413 | this._ip = this._stack.pop() >= 0 ? jmp : this._ip; 1414 | return done(); 1415 | } 1416 | 1417 | Frame.prototype.ifgt = function(done) { 1418 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1419 | this._ip = this._stack.pop() > 0 ? jmp : this._ip; 1420 | return done(); 1421 | } 1422 | 1423 | Frame.prototype.ifle = function(done) { 1424 | var jmp = this._ip - 1 + Numeric.getInt(this._read16()); 1425 | this._ip = this._stack.pop() <= 0 ? jmp : this._ip; 1426 | return done(); 1427 | } 1428 | 1429 | Frame.prototype.i2l = function(done) { 1430 | return done(); 1431 | } 1432 | 1433 | Frame.prototype.i2f = function(done) { 1434 | return done(); 1435 | } 1436 | 1437 | Frame.prototype.i2d = function(done) { 1438 | return done(); 1439 | } 1440 | 1441 | Frame.prototype.i2b = function(done) { 1442 | return done(); 1443 | } 1444 | 1445 | Frame.prototype.i2c = function(done) { 1446 | return done(); 1447 | } 1448 | 1449 | Frame.prototype.i2s = function(done) { 1450 | return done(); 1451 | } 1452 | 1453 | Frame.prototype.l2i = function(done) { 1454 | return done(); 1455 | } 1456 | 1457 | Frame.prototype.l2d = function(done) { 1458 | return done(); 1459 | } 1460 | 1461 | Frame.prototype.l2f = function(done) { 1462 | return done(); 1463 | } 1464 | 1465 | Frame.prototype.d2i = function(done) { 1466 | return done(); 1467 | } 1468 | 1469 | Frame.prototype.d2l = function(done) { 1470 | return done(); 1471 | } 1472 | 1473 | Frame.prototype.d2f = function(done) { 1474 | return done(); 1475 | } 1476 | 1477 | Frame.prototype.f2d = function(done) { 1478 | return done(); 1479 | } 1480 | 1481 | Frame.prototype.f2i = function(done) { 1482 | return done(); 1483 | } 1484 | 1485 | Frame.prototype.f2l = function(done) { 1486 | return done(); 1487 | } 1488 | 1489 | Frame.prototype.goto = function(done) { 1490 | this._ip += Numeric.getInt(this._read16()) - 1; 1491 | return done(); 1492 | } 1493 | 1494 | Frame.prototype.goto_w = function(done) { 1495 | this._ip += Numeric.getInt(this._read32()) - 1; 1496 | return done(); 1497 | } 1498 | 1499 | Frame.prototype.ifnull = function(done) { 1500 | var ref = this._stack.pop(); 1501 | if (!ref) { 1502 | this._ip += Numeric.getInt(this._read16()) - 1; 1503 | } 1504 | return done(); 1505 | } 1506 | 1507 | Frame.prototype.ifnonnull = function(done) { 1508 | var ref = this._stack.pop(); 1509 | if (!!ref) { 1510 | this._ip += Numeric.getInt(this._read16()) - 1; 1511 | } 1512 | return done(); 1513 | } 1514 | 1515 | Frame.prototype.putfield = function(done) { 1516 | var idx = this._read16(); 1517 | var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; 1518 | var val = this._stack.pop(); 1519 | var obj = this._stack.pop(); 1520 | if (!obj) { 1521 | this._throw(CLASSES.newException("java/lang/NullPointerException")); 1522 | } else { 1523 | obj[fieldName] = val; 1524 | } 1525 | return done(); 1526 | } 1527 | 1528 | Frame.prototype.getfield = function(done) { 1529 | var idx = this._read16(); 1530 | var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; 1531 | var obj = this._stack.pop(); 1532 | if (!obj) { 1533 | this._throw(CLASSES.newException("java/lang/NullPointerException")); 1534 | } else { 1535 | this._stack.push(obj[fieldName]); 1536 | } 1537 | return done(); 1538 | } 1539 | 1540 | 1541 | Frame.prototype.new = function(done) { 1542 | var idx = this._read16(); 1543 | var className = this._cp[this._cp[idx].name_index].bytes; 1544 | this._stack.push(CLASSES.newObject(className)); 1545 | return done(); 1546 | } 1547 | 1548 | Frame.prototype.getstatic = function(done) { 1549 | var idx = this._read16(); 1550 | var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes; 1551 | var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; 1552 | this._stack.push(CLASSES.getStaticField(className, fieldName)); 1553 | return done(); 1554 | } 1555 | 1556 | Frame.prototype.putstatic = function(done) { 1557 | var idx = this._read16(); 1558 | var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes; 1559 | var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; 1560 | CLASSES.setStaticField(className, fieldName, this._stack.pop()); 1561 | return done(); 1562 | } 1563 | 1564 | Frame.prototype.invokestatic = function(done) { 1565 | var self = this; 1566 | 1567 | var idx = this._read16(); 1568 | 1569 | var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes; 1570 | var methodName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; 1571 | var signature = Signature.parse(this._cp[this._cp[this._cp[idx].name_and_type_index].signature_index].bytes); 1572 | 1573 | var args = []; 1574 | for (var i=0; i high) { 1758 | jmp = def; 1759 | } else { 1760 | this._ip += (val - low) << 2; 1761 | jmp = this._read32(); 1762 | } 1763 | 1764 | this._ip = startip - 1 + Numeric.getInt(jmp); 1765 | 1766 | return done(); 1767 | } 1768 | 1769 | Frame.prototype.lookupswitch = function(done) { 1770 | 1771 | var startip = this._ip; 1772 | 1773 | while ((this._ip % 4) != 0) { 1774 | this._ip++; 1775 | } 1776 | 1777 | var jmp = this._read32(); 1778 | var size = this._read32(); 1779 | var val = this._stack.pop(); 1780 | 1781 | lookup: 1782 | for(var i=0; i= val) { 1789 | break lookup; 1790 | } 1791 | } 1792 | 1793 | this._ip = startip - 1 + Numeric.getInt(jmp); 1794 | 1795 | return done(); 1796 | } 1797 | 1798 | Frame.prototype.instanceof = function(done) { 1799 | var idx = this._read16(); 1800 | var className = this._cp[this._cp[idx].name_index].bytes; 1801 | var obj = this._stack.pop(); 1802 | if (obj.getClassName() === className) { 1803 | this._stack.push(true); 1804 | } else { 1805 | this._stack.push(false); 1806 | } 1807 | return done(); 1808 | } 1809 | 1810 | Frame.prototype.checkcast = function(done) { 1811 | var idx = this._read16(); 1812 | var type = this._cp[this._cp[idx].name_index].bytes; 1813 | return done(); 1814 | } 1815 | 1816 | 1817 | Frame.prototype.athrow = function(done) { 1818 | this._throw(this._stack.pop()); 1819 | return done(); 1820 | } 1821 | 1822 | Frame.prototype.wide = function(done) { 1823 | this._widened = true; 1824 | return done(); 1825 | } 1826 | 1827 | Frame.prototype.monitorenter = function(done) { 1828 | var obj = this._stack.pop(); 1829 | if (!obj) { 1830 | this._throw(CLASSES.newException("java/lang/NullPointerException")); 1831 | } else if (obj.hasOwnProperty("$lock$")) { 1832 | this._stack.push(obj); 1833 | this._ip--; 1834 | SCHEDULER.yield(); 1835 | } else { 1836 | obj["$lock$"] = "locked"; 1837 | } 1838 | return done(); 1839 | } 1840 | 1841 | Frame.prototype.monitorexit = function(done) { 1842 | var obj = this._stack.pop(); 1843 | if (!obj) { 1844 | this._throw(CLASSES.newException("java/lang/NullPointerException")); 1845 | } else { 1846 | delete obj["$lock$"]; 1847 | SCHEDULER.yield(); 1848 | } 1849 | return done(); 1850 | } 1851 | 1852 | -------------------------------------------------------------------------------- /libs/java/io/IOException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("../lang/Exception.js"); 8 | 9 | var IOException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new IOException(); 14 | } 15 | } 16 | 17 | util.inherits(IOException, Exception); 18 | 19 | IOException.getClassName = function() { 20 | return "java/io/IOException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/io/PrintStream.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var out = module.exports = function() { 9 | if (this instanceof out) { 10 | } else { 11 | return new out(); 12 | } 13 | }; 14 | 15 | out.getClassName = function() { 16 | return "java/io/PrintStream"; 17 | } 18 | 19 | out.prototype["print"] = function() { 20 | util.print.apply(null, arguments); 21 | }; 22 | 23 | out.prototype["println"] = function() { 24 | util.print.apply(null, arguments); 25 | util.print("\n"); 26 | }; 27 | 28 | out.prototype["format"] = function(fmt, args) { 29 | util.print(util.format.apply(null, [fmt].concat(args))); 30 | } 31 | -------------------------------------------------------------------------------- /libs/java/lang/ArithmeticException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var ArithmeticException = module.exports = function() { 10 | if (this instanceof ArithmeticException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new ArithmeticException(); 14 | } 15 | } 16 | 17 | util.inherits(ArithmeticException, RuntimeException); 18 | 19 | ArithmeticException.getClassName = function() { 20 | return "java/lang/ArithmeticException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/ArrayIndexOutOfBoundsException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var IndexOutOfBoundsException = require("./IndexOutOfBoundsException.js"); 8 | 9 | var ArrayIndexOutOfBoundsException = module.exports = function() { 10 | if (this instanceof IndexOutOfBoundsException) { 11 | IndexOutOfBoundsException.call(this); 12 | } else { 13 | return new ArrayIndexOutOfBoundsException(); 14 | } 15 | } 16 | 17 | util.inherits(ArrayIndexOutOfBoundsException, IndexOutOfBoundsException); 18 | 19 | ArrayIndexOutOfBoundsException.getClassName = function() { 20 | return "java/lang/ArrayIndexOutOfBoundsException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/ArrayStoreException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var ArrayStoreException = module.exports = function() { 10 | if (this instanceof ArrayStoreException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new ArrayStoreException(); 14 | } 15 | } 16 | 17 | util.inherits(ArrayStoreException, RuntimeException); 18 | 19 | ArrayStoreException.getClassName = function() { 20 | return "java/lang/ArrayStoreException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/Class.js: -------------------------------------------------------------------------------- 1 | 2 | var Clazz = module.exports = function(className, clazz) { 3 | if (this instanceof Clazz) { 4 | this._className = className; 5 | this._clazz = clazz; 6 | } else { 7 | return new Clazz(className, clazz); 8 | } 9 | } 10 | 11 | Clazz.getClassName = function() { 12 | return "java/lang/Class"; 13 | } 14 | 15 | Clazz.forName = function(className) { 16 | return new Clazz(className, CLASSES.getClass(className)); 17 | } 18 | 19 | Clazz.prototype.newInstance = function() { 20 | return CLASSES.newObject(this._className); 21 | 22 | } -------------------------------------------------------------------------------- /libs/java/lang/ClassCastException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var ClassCastException = module.exports = function() { 10 | if (this instanceof ClassCastException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new ClassCastException(); 14 | } 15 | } 16 | 17 | util.inherits(ClassCastException, RuntimeException); 18 | 19 | ClassCastException.getClassName = function() { 20 | return "java/lang/ClassCastException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/ClassNotFoundException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var ClassNotFoundException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new ClassNotFoundException(); 14 | } 15 | } 16 | 17 | util.inherits(ClassNotFoundException, Exception); 18 | 19 | ClassNotFoundException.getClassName = function() { 20 | return "java/lang/ClassNotFoundException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/ClassNotSupportedException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var ClassNotSupportedException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new ClassNotSupportedException(); 14 | } 15 | } 16 | 17 | util.inherits(ClassNotSupportedException, Exception); 18 | 19 | ClassNotSupportedException.getClassName = function() { 20 | return "java/lang/ClassNotSupportedException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/Exception.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Throwable = require("./Throwable.js"); 8 | 9 | var Exception = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Throwable.call(this); 12 | } else { 13 | return new Exception(); 14 | } 15 | } 16 | 17 | util.inherits(Exception, Throwable); 18 | 19 | Exception.getClassName = function() { 20 | return "java/lang/Exception"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/IllegalArgumentException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var IllegalArgumentException = module.exports = function() { 10 | if (this instanceof IllegalArgumentException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new IllegalArgumentException(); 14 | } 15 | } 16 | 17 | util.inherits(IllegalArgumentException, RuntimeException); 18 | 19 | IllegalArgumentException.getClassName = function() { 20 | return "java/lang/IllegalArgumentException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/IllegalMonitorStateException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var IllegalMonitorStateException = module.exports = function() { 10 | if (this instanceof IllegalMonitorStateException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new IllegalMonitorStateException(); 14 | } 15 | } 16 | 17 | util.inherits(IllegalMonitorStateException, RuntimeException); 18 | 19 | IllegalMonitorStateException.getClassName = function() { 20 | return "java/lang/IllegalMonitorStateException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/IllegalThreadStateException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var IllegalThreadStateException = module.exports = function() { 10 | if (this instanceof IllegalThreadStateException) { 11 | IllegalArgumentException.call(this); 12 | } else { 13 | return new IllegalThreadStateException(); 14 | } 15 | } 16 | 17 | util.inherits(IllegalThreadStateException, IllegalArgumentException); 18 | 19 | IllegalThreadStateException.getClassName = function() { 20 | return "java/lang/IllegalThreadStateException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/IlligalAccessException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var IlligalAccessException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new IlligalAccessException(); 14 | } 15 | } 16 | 17 | util.inherits(IlligalAccessException, Exception); 18 | 19 | IlligalAccessException.getClassName = function() { 20 | return "java/lang/IlligalAccessException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/IndexOutOfBoundsException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var IndexOutOfBoundsException = module.exports = function() { 10 | if (this instanceof IndexOutOfBoundsException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new IndexOutOfBoundsException(); 14 | } 15 | } 16 | 17 | util.inherits(IndexOutOfBoundsException, RuntimeException); 18 | 19 | IndexOutOfBoundsException.getClassName = function() { 20 | return "java/lang/IndexOutOfBoundsException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/InstantiationException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var InstantiationException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new InstantiationException(); 14 | } 15 | } 16 | 17 | util.inherits(InstantiationException, Exception); 18 | 19 | InstantiationException.getClassName = function() { 20 | return "java/lang/InstantiationException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/Integer.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var Integer = module.exports = function() { 7 | if (this instanceof Integer) { 8 | } else { 9 | return new Integer(); 10 | } 11 | } 12 | 13 | Integer.getClassName = function() { 14 | return "java/lang/Integer"; 15 | } 16 | 17 | Integer.parseInt = function() { 18 | return parseInt.apply(null, arguments); 19 | } 20 | 21 | Integer.valueOf = function() { 22 | if (arguments.length === 0) return "0"; 23 | return arguments[0].toString(); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libs/java/lang/InterruptedException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var InterruptedException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new InterruptedException(); 14 | } 15 | } 16 | 17 | util.inherits(InterruptedException, Exception); 18 | 19 | InterruptedException.getClassName = function() { 20 | return "java/lang/InterruptedException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/NegativeArraySizeException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var NegativeArraySizeException = module.exports = function() { 10 | if (this instanceof NegativeArraySizeException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new NegativeArraySizeException(); 14 | } 15 | } 16 | 17 | util.inherits(NegativeArraySizeException, RuntimeException); 18 | 19 | NegativeArraySizeException.getClassName = function() { 20 | return "java/lang/NegativeArraySizeException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/NoSuchMethodException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var NoSuchMethodException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new NoSuchMethodException(); 14 | } 15 | } 16 | 17 | util.inherits(NoSuchMethodException, Exception); 18 | 19 | NoSuchMethodException.getClassName = function() { 20 | return "java/lang/NoSuchMethodException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/NullPointerException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var NullPointerException = module.exports = function() { 10 | if (this instanceof NullPointerException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new NullPointerException(); 14 | } 15 | } 16 | 17 | util.inherits(NullPointerException, RuntimeException); 18 | 19 | NullPointerException.getClassName = function() { 20 | return "java/lang/NullPointerException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/NumberFormatException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var NumberFormatException = module.exports = function() { 10 | if (this instanceof NumberFormatException) { 11 | IllegalArgumentException.call(this); 12 | } else { 13 | return new NumberFormatException(); 14 | } 15 | } 16 | 17 | util.inherits(NumberFormatException, IllegalArgumentException); 18 | 19 | NumberFormatException.getClassName = function() { 20 | return "java/lang/NumberFormatException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/Object.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var Object = module.exports = function() { 9 | if (this instanceof Object) { 10 | this._hashCode = null; 11 | } else { 12 | return new Object(); 13 | } 14 | } 15 | 16 | Object.getClassName = function() { 17 | return "java/lang/Object"; 18 | } 19 | 20 | 21 | Object.prototype[""] = function() { 22 | return this; 23 | } 24 | 25 | Object.prototype["toString"] = function() { 26 | return this.getClassName() + "@" + this.hashCode().toString(16); 27 | } 28 | 29 | Object.prototype["hashCode"] = function() { 30 | if (!this._hashCode) { 31 | this._hashCode = Math.floor(Math.random() * 0xffffffff); 32 | } 33 | return this._hashCode; 34 | } 35 | 36 | Object.prototype["equals"] = function() { 37 | return this === arguments[0]; 38 | } 39 | 40 | Object.prototype["clone"] = function() { 41 | var o = {}; 42 | for(var name in this) { 43 | o[name] = this[name]; 44 | } 45 | return o; 46 | } -------------------------------------------------------------------------------- /libs/java/lang/RuntimeException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Exception = require("./Exception.js"); 8 | 9 | var RuntimeException = module.exports = function() { 10 | if (this instanceof Exception) { 11 | Exception.call(this); 12 | } else { 13 | return new RuntimeException(); 14 | } 15 | } 16 | 17 | util.inherits(RuntimeException, Exception); 18 | 19 | RuntimeException.getClassName = function() { 20 | return "java/lang/RuntimeException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/SecurityException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var SecurityException = module.exports = function() { 10 | if (this instanceof SecurityException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new SecurityException(); 14 | } 15 | } 16 | 17 | util.inherits(SecurityException, RuntimeException); 18 | 19 | SecurityException.getClassName = function() { 20 | return "java/lang/SecurityException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/lang/String.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Object = require("./Object.js"); 8 | 9 | var String = module.exports = function(s) { 10 | if (this instanceof String) { 11 | this._str = s; 12 | } else { 13 | return new String(s); 14 | } 15 | } 16 | 17 | util.inherits(String, Object); 18 | 19 | String.getClassName = function() { 20 | return "java/lang/String"; 21 | } 22 | 23 | String.prototype[""] = function() { 24 | return this; 25 | } 26 | 27 | String.prototype["toString"] = function() { 28 | return this._str.toString(); 29 | } 30 | 31 | String["valueOf"] = function() { 32 | if (arguments.length === 0) return ""; 33 | return arguments[0].toString(); 34 | } -------------------------------------------------------------------------------- /libs/java/lang/StringBuilder.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Object = require("./Object.js"); 8 | 9 | var StringBuilder = module.exports = function(p) { 10 | if (this instanceof StringBuilder) { 11 | if (typeof p === "number") { 12 | this._buf = new Array(p).join(' '); 13 | } else { 14 | this._buf = p || ""; 15 | } 16 | } else { 17 | return new StringBuilder(p); 18 | } 19 | } 20 | 21 | util.inherits(StringBuilder, Object); 22 | 23 | StringBuilder.getClassName = function() { 24 | return "java/lang/StringBuilder"; 25 | } 26 | 27 | 28 | StringBuilder.prototype[""] = function() { 29 | for(var i=0; i 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var StringIndexOutOfBoundsException = module.exports = function() { 10 | if (this instanceof IndexOutOfBoundsException) { 11 | IndexOutOfBoundsException.call(this); 12 | } else { 13 | return new StringIndexOutOfBoundsException(); 14 | } 15 | } 16 | 17 | util.inherits(StringIndexOutOfBoundsException, IndexOutOfBoundsException); 18 | 19 | StringIndexOutOfBoundsException.getClassName = function() { 20 | return "java/lang/StringIndexOutOfBoundsException"; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /libs/java/lang/System.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var System = module.exports = function() { 9 | if (this instanceof System) { 10 | } else { 11 | return new System(); 12 | } 13 | } 14 | 15 | System.getClassName = function() { 16 | return "java/lang/System"; 17 | } 18 | 19 | 20 | System["exit"] = function() { 21 | process.exit(); 22 | } 23 | 24 | System["out"] = { 25 | "print": function() { 26 | util.print.apply(null, arguments); 27 | }, 28 | "println": function() { 29 | util.print.apply(null, arguments); 30 | util.print("\n"); 31 | }, 32 | "format": function(fmt, args) { 33 | util.print(util.format.apply(null, [fmt].concat(args))); 34 | } 35 | } 36 | 37 | System["currentTimeMillis"] = function() { 38 | return new Date().getTime(); 39 | } 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /libs/java/lang/Thread.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var Object = require("./Object.js"); 8 | var Frame = require("./../../frame.js"); 9 | var Thread = require("./../../thread.js"); 10 | 11 | var AThread = module.exports = function() { 12 | if (this instanceof AThread) { 13 | this.thread = new Thread(); 14 | } else { 15 | return new AThread(); 16 | } 17 | } 18 | 19 | util.inherits(String, Object); 20 | 21 | 22 | AThread.getClassName = function() { 23 | return "java/lang/Thread"; 24 | } 25 | 26 | AThread.prototype[""] = function(instance) { 27 | this._instance = instance; 28 | } 29 | 30 | AThread.prototype.setName = function(name) { 31 | this.thread.setName(name); 32 | } 33 | 34 | AThread.prototype.getName = function() { 35 | return this.thread.getName(); 36 | } 37 | 38 | AThread.prototype.setPriority = function(priority) { 39 | this.thread.setPriority(priority); 40 | } 41 | 42 | AThread.prototype.getPriority = function() { 43 | return this.thread.getPriority(); 44 | } 45 | 46 | AThread.prototype["start"] = function() { 47 | var self = this; 48 | var pid = THREADS.add(this.thread); 49 | if (this._instance["run"] instanceof Frame) { 50 | this._instance["run"].setPid(pid); 51 | this._instance["run"].run([this._instance], function() { 52 | THREADS.remove(pid); 53 | }); 54 | } else { 55 | self._instance["run"](); 56 | THREADS.remove(pid); 57 | } 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /libs/java/lang/Throwable.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var Throwable = module.exports = function() { 9 | if (this instanceof Throwable) { 10 | this.message = ""; 11 | this.cause = null; 12 | } else { 13 | return new Throwable(); 14 | } 15 | } 16 | 17 | util.inherits(Throwable, Error); 18 | 19 | Throwable.getClassName = function() { 20 | return "java/lang/Throwable"; 21 | } 22 | 23 | Throwable.prototype[""] = function() { 24 | switch(arguments.length) { 25 | case 1: 26 | if (typeof arguments[0] !== "object") { 27 | this.message = arguments[0]; 28 | } else { 29 | this.cause = arguments[0]; 30 | } 31 | break; 32 | case 2: 33 | this.message = arguments[0]; 34 | this.cause = arguments[1]; 35 | break; 36 | } 37 | } 38 | 39 | Throwable.prototype.initCause = function(cause) { 40 | this.cause = cause; 41 | } 42 | 43 | Throwable.prototype.getMessage = function() { 44 | return this.message; 45 | } 46 | 47 | Throwable.prototype.getCause = function() { 48 | return this.cause; 49 | } 50 | 51 | Throwable.prototype.toString = function() { 52 | if (this.message) { 53 | return util.format("Exception %s: %s", this.getClassName(), this.message); 54 | } 55 | return util.format("Exception %s", this.getClassName()); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /libs/java/util/EmptyStackException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var EmptyStackException = module.exports = function() { 10 | if (this instanceof EmptyStackException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new EmptyStackException(); 14 | } 15 | } 16 | 17 | util.inherits(EmptyStackException, RuntimeException); 18 | 19 | EmptyStackException.getClassName = function() { 20 | return "java/lang/EmptyStackException.js"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/java/util/NoSuchElementException.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var RuntimeException = require("./RuntimeException.js"); 8 | 9 | var NoSuchMethodException = module.exports = function() { 10 | if (this instanceof NoSuchMethodException) { 11 | RuntimeException.call(this); 12 | } else { 13 | return new NoSuchMethodException(); 14 | } 15 | } 16 | 17 | util.inherits(NoSuchMethodException, RuntimeException); 18 | 19 | NoSuchMethodException.getClassName = function() { 20 | return "java/lang/NoSuchMethodException"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /libs/jvm.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | var fs = require("fs"); 8 | var path = require("path"); 9 | var EE = require("events").EventEmitter; 10 | 11 | var globalizer = require("./util/globalizer"); 12 | 13 | var Classes = require("./classes"); 14 | var Threads = require("./threads"); 15 | var Scheduler = require("./scheduler"); 16 | var Logger = require("./logger"); 17 | 18 | var OPCODES = require("./opcodes"); 19 | var Thread = require("./thread"); 20 | 21 | var JVM = module.exports = function() { 22 | if (this instanceof JVM) { 23 | JVM.super_.call(this); 24 | globalizer.add("LOG", new Logger()); 25 | globalizer.add("CLASSES", new Classes()); 26 | globalizer.add("THREADS", new Threads()); 27 | globalizer.add("SCHEDULER", new Scheduler()); 28 | globalizer.add("OPCODES", OPCODES); 29 | 30 | THREADS.add(new Thread("main")); 31 | 32 | this.entryPoint = { 33 | className: null, 34 | methodName: "main" 35 | }; 36 | } else { 37 | return new JVM(); 38 | } 39 | } 40 | 41 | util.inherits(JVM, EE); 42 | 43 | JVM.prototype.setEntryPointClassName = function(className) { 44 | this.entryPoint.className = className; 45 | } 46 | 47 | JVM.prototype.setEntryPointMethodName = function(methodName) { 48 | this.entryPoint.methodName = methodName; 49 | } 50 | 51 | JVM.prototype.setLogLevel = function(level) { 52 | LOG.setLogLevel(level); 53 | } 54 | 55 | JVM.prototype.loadClassFile = function(fileName) { 56 | return CLASSES.loadClassFile(fileName); 57 | } 58 | 59 | JVM.prototype.loadClassFiles = function(dirName) { 60 | var self = this; 61 | CLASSES.addPath(dirName); 62 | var files = fs.readdirSync(dirName); 63 | files.forEach(function(file) { 64 | var p = util.format("%s/%s", dirName, file); 65 | var stat = fs.statSync(p); 66 | if (stat.isFile()) { 67 | if (path.extname(file) === ".class") { 68 | self.loadClassFile(p); 69 | } 70 | } else if (stat.isDirectory()) { 71 | self.loadClassFiles(p); 72 | } 73 | }); 74 | } 75 | 76 | JVM.prototype.loadJSFile = function(fileName) { 77 | return CLASSES.loadJSFile(fileName); 78 | } 79 | 80 | JVM.prototype.loadJarFile = function(fileName) { 81 | return CLASSES.loadJarFile(fileName); 82 | } 83 | 84 | JVM.prototype.run = function() { 85 | var self = this; 86 | 87 | CLASSES.clinit(); 88 | 89 | var entryPoint = CLASSES.getEntryPoint(this.entryPoint.className, this.entryPoint.methodName); 90 | if (!entryPoint) { 91 | throw new Error("Entry point method is not found."); 92 | } 93 | 94 | entryPoint.run(arguments, function(code) { 95 | var exit = function() { 96 | SCHEDULER.tick(0, function() { 97 | if (THREADS.count() === 1) { 98 | THREADS.remove(0); 99 | self.emit("exit", code); 100 | } else { 101 | exit(); 102 | } 103 | }); 104 | }; 105 | exit(); 106 | }); 107 | } 108 | 109 | -------------------------------------------------------------------------------- /libs/logger.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var util = require("util"); 7 | 8 | var LEVELS = { 9 | DEBUG: 1 << 0, 10 | ERROR: 1 << 1, 11 | INFO: 1 << 2, 12 | WARN: 1 << 3, 13 | check: function (levels, level) { 14 | return (levels & level) === level; 15 | } 16 | }; 17 | 18 | var LOG = Object.freeze({ 19 | debug: console.debug || util.debug || console.log, 20 | error: console.error || util.error || console.log, 21 | info: console.info || util.print || console.log, 22 | warn: console.warn || util.print || console.log 23 | }); 24 | 25 | var Logger = module.exports = function (levels) { 26 | if (this instanceof Logger) { 27 | this.levels = levels || (LEVELS.DEBUG | LEVELS.ERROR | LEVELS.INFO | LEVELS.WARN); 28 | } else { 29 | return new Logger(levels); 30 | } 31 | }; 32 | 33 | Logger.prototype.setLogLevel = function (levels) { 34 | this.levels = levels; 35 | } 36 | 37 | Logger.prototype.debug = function (msg) { 38 | if (LEVELS.check(this.levels, LEVELS.DEBUG)) { 39 | LOG.debug(msg); 40 | } 41 | } 42 | 43 | Logger.prototype.error = function (msg) { 44 | if (LEVELS.check(this.levels, LEVELS.ERROR)) { 45 | LOG.error(msg); 46 | } 47 | } 48 | 49 | Logger.prototype.info = function (msg) { 50 | if (LEVELS.check(this.levels, LEVELS.INFO)) { 51 | LOG.info("INFO: " + msg); 52 | } 53 | } 54 | 55 | Logger.prototype.warn = function (msg) { 56 | if (LEVELS.check(this.levels, LEVELS.WARN)) { 57 | LOG.warn("WARN: " + msg); 58 | } 59 | } -------------------------------------------------------------------------------- /libs/opcodes.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var OPCODES = module.exports = { 7 | "nop": 0x00, 8 | "aconst_null": 0x01, 9 | "iconst_m1": 0x02, 10 | "iconst_0": 0x03, 11 | "iconst_1": 0x04, 12 | "iconst_2": 0x05, 13 | "iconst_3": 0x06, 14 | "iconst_4": 0x07, 15 | "iconst_5": 0x08, 16 | "lconst_0": 0x09, 17 | "lconst_1": 0x0A, 18 | "fconst_0": 0x0B, 19 | "fconst_1": 0x0C, 20 | "fconst_2": 0x0D, 21 | "dconst_0": 0x0E, 22 | "dconst_1": 0x0F, 23 | "bipush": 0x10, 24 | "sipush": 0x11, 25 | "ldc": 0x12, 26 | "ldc_w": 0x13, 27 | "ldc2_w": 0x14, 28 | "iload": 0x15, 29 | "lload": 0x16, 30 | "fload": 0x17, 31 | "dload": 0x18, 32 | "aload": 0x19, 33 | "iload_0": 0x1A, 34 | "iload_1": 0x1B, 35 | "iload_2": 0x1C, 36 | "iload_3": 0x1D, 37 | "lload_0": 0x1E, 38 | "lload_1": 0x1F, 39 | "lload_2": 0x20, 40 | "lload_3": 0x21, 41 | "fload_0": 0x22, 42 | "fload_1": 0x23, 43 | "fload_2": 0x24, 44 | "fload_3": 0x25, 45 | "dload_0": 0x26, 46 | "dload_1": 0x27, 47 | "dload_2": 0x28, 48 | "dload_3": 0x29, 49 | "aload_0": 0x2A, 50 | "aload_1": 0x2B, 51 | "aload_2": 0x2C, 52 | "aload_3": 0x2D, 53 | "iaload": 0x2E, 54 | "laload": 0x2F, 55 | "faload": 0x30, 56 | "daload": 0x31, 57 | "aaload": 0x32, 58 | "baload": 0x33, 59 | "caload": 0x34, 60 | "saload": 0x35, 61 | "istore": 0x36, 62 | "lstore": 0x37, 63 | "fstore": 0x38, 64 | "dstore": 0x39, 65 | "astore": 0x3A, 66 | "istore_0": 0x3B, 67 | "istore_1": 0x3C, 68 | "istore_2": 0x3D, 69 | "istore_3": 0x3E, 70 | "lstore_0": 0x3F, 71 | "lstore_1": 0x40, 72 | "lstore_2": 0x41, 73 | "lstore_3": 0x42, 74 | "fstore_0": 0x43, 75 | "fstore_1": 0x44, 76 | "fstore_2": 0x45, 77 | "fstore_3": 0x46, 78 | "dstore_0": 0x47, 79 | "dstore_1": 0x48, 80 | "dstore_2": 0x49, 81 | "dstore_3": 0x4A, 82 | "astore_0": 0x4B, 83 | "astore_1": 0x4C, 84 | "astore_2": 0x4D, 85 | "astore_3": 0x4E, 86 | "iastore": 0x4F, 87 | "lastore": 0x50, 88 | "fastore": 0x51, 89 | "dastore": 0x52, 90 | "aastore": 0x53, 91 | "bastore": 0x54, 92 | "castore": 0x55, 93 | "sastore": 0x56, 94 | "pop": 0x57, 95 | "pop2": 0x58, 96 | "dup": 0x59, 97 | "dup_x1": 0x5A, 98 | "dup_x2": 0x5B, 99 | "dup2": 0x5C, 100 | "dup2_x1": 0x5D, 101 | "dup2_x2": 0x5E, 102 | "swap": 0x5F, 103 | "iadd": 0x60, 104 | "ladd": 0x61, 105 | "fadd": 0x62, 106 | "dadd": 0x63, 107 | "isub": 0x64, 108 | "lsub": 0x65, 109 | "fsub": 0x66, 110 | "dsub": 0x67, 111 | "imul": 0x68, 112 | "lmul": 0x69, 113 | "fmul": 0x6A, 114 | "dmul": 0x6B, 115 | "idiv": 0x6C, 116 | "ldiv": 0x6D, 117 | "fdiv": 0x6E, 118 | "ddiv": 0x6F, 119 | "irem": 0x70, 120 | "lrem": 0x71, 121 | "frem": 0x72, 122 | "drem": 0x73, 123 | "ineg": 0x74, 124 | "lneg": 0x75, 125 | "fneg": 0x76, 126 | "dneg": 0x77, 127 | "ishl": 0x78, 128 | "lshl": 0x79, 129 | "ishr": 0x7A, 130 | "lshr": 0x7B, 131 | "iushr": 0x7C, 132 | "lushr": 0x7D, 133 | "iand": 0x7E, 134 | "land": 0x7F, 135 | "ior": 0x80, 136 | "lor": 0x81, 137 | "ixor": 0x82, 138 | "lxor": 0x83, 139 | "iinc": 0x84, 140 | "i2l": 0x85, 141 | "i2f": 0x86, 142 | "i2d": 0x87, 143 | "l2i": 0x88, 144 | "l2f": 0x89, 145 | "l2d": 0x8A, 146 | "f2i": 0x8B, 147 | "f2l": 0x8C, 148 | "f2d": 0x8D, 149 | "d2i": 0x8E, 150 | "d2l": 0x8F, 151 | "d2f": 0x90, 152 | "i2b": 0x91, 153 | "i2c": 0x92, 154 | "i2s": 0x93, 155 | "lcmp": 0x94, 156 | "fcmpl": 0x95, 157 | "fcmpg": 0x96, 158 | "dcmpl": 0x97, 159 | "dcmpg": 0x98, 160 | "ifeq": 0x99, 161 | "ifne": 0x9A, 162 | "iflt": 0x9B, 163 | "ifge": 0x9C, 164 | "ifgt": 0x9D, 165 | "ifle": 0x9E, 166 | "if_icmpeq": 0x9F, 167 | "if_icmpne": 0xA0, 168 | "if_icmplt": 0xA1, 169 | "if_icmpge": 0xA2, 170 | "if_icmpgt": 0xA3, 171 | "if_icmple": 0xA4, 172 | "if_acmpeq": 0xA5, 173 | "if_acmpne": 0xA6, 174 | "goto": 0xA7, 175 | "jsr": 0xA8, 176 | "ret": 0xA9, 177 | "tableswitch": 0xAA, 178 | "lookupswitch": 0xAB, 179 | "ireturn": 0xAC, 180 | "lreturn": 0xAD, 181 | "freturn": 0xAE, 182 | "dreturn": 0xAF, 183 | "areturn": 0xB0, 184 | "return": 0xB1, 185 | "getstatic": 0xB2, 186 | "putstatic": 0xB3, 187 | "getfield": 0xB4, 188 | "putfield": 0xB5, 189 | "invokevirtual": 0xB6, 190 | "invokespecial": 0xB7, 191 | "invokestatic": 0xB8, 192 | "invokeinterface": 0xB9, 193 | "new": 0xBB, 194 | "newarray": 0xBC, 195 | "anewarray": 0xBD, 196 | "arraylength": 0xBE, 197 | "athrow": 0xBF, 198 | "checkcast": 0xC0, 199 | "instanceof": 0xC1, 200 | "monitorenter": 0xC2, 201 | "monitorexit": 0xC3, 202 | "wide": 0xC4, 203 | "multianewarray": 0xC5, 204 | "ifnull": 0xC6, 205 | "ifnonnull": 0xC7, 206 | "goto_w": 0xC8, 207 | "jsr_w": 0xC9, 208 | 209 | toString: function(opCode) { 210 | if ( !this._cache ) { 211 | this._cache = new Array(256); 212 | } 213 | if ( this._cache[opCode] ) { 214 | return this._cache[opCode]; 215 | } 216 | for(var opName in this) { 217 | if (this[opName] === opCode) { 218 | return this._cache[opCode] = opName; 219 | } 220 | } 221 | return null; 222 | } 223 | }; 224 | -------------------------------------------------------------------------------- /libs/scheduler.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var MODE = { 7 | NORMAL: 0, 8 | SYNC: 1, 9 | YIELD: 2 10 | }; 11 | 12 | var Scheduler = module.exports = function(mticks) { 13 | if (this instanceof Scheduler) { 14 | this._ticks = 0; 15 | this._mode = MODE.NORMAL; 16 | } else { 17 | return new Scheduler(mticks); 18 | } 19 | } 20 | 21 | Scheduler.prototype.tick = function(pid, fn) { 22 | switch(this._mode) { 23 | case MODE.SYNC: 24 | fn(); 25 | break; 26 | case MODE.YIELD: 27 | this._mode = MODE.NORMAL; 28 | this._ticks = 0; 29 | (setImmediate || process.nextTick)(fn); 30 | break; 31 | case MODE.NORMAL: 32 | if (++this._ticks > THREADS.getThread(pid).getPriority()) { 33 | this._ticks = 0; 34 | (setImmediate || process.nextTick)(fn); 35 | } else { 36 | fn(); 37 | } 38 | break; 39 | } 40 | } 41 | 42 | Scheduler.prototype.yield = function() { 43 | this._mode = MODE.YIELD; 44 | } 45 | 46 | Scheduler.prototype.sync = function(fn) { 47 | this._mode = MODE.SYNC; 48 | fn(); 49 | this._mode = MODE.NORMAL; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /libs/thread.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var Thread = module.exports = function(name) { 7 | if (this instanceof Thread) { 8 | this.name = name || "noname"; 9 | this.priority = (Thread.MAX_PRIORITY + Thread.MIN_PRIORITY) >> 1; 10 | } else { 11 | return new Thread(name); 12 | } 13 | } 14 | 15 | Thread.prototype.setName = function(name) { 16 | this.name = name; 17 | } 18 | 19 | Thread.prototype.getName = function(name) { 20 | return this.name; 21 | } 22 | 23 | Thread.MIN_PRIORITY = 0; 24 | Thread.MAX_PRIORITY = 100; 25 | 26 | Thread.prototype.setPriority = function(priority) { 27 | this.priority = priority; 28 | } 29 | 30 | Thread.prototype.getPriority = function() { 31 | return this.priority; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /libs/threads.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var Threads = module.exports = function() { 7 | this.threads = []; 8 | this.empty = []; 9 | } 10 | 11 | Threads.prototype.add = function(thread) { 12 | if (this.empty.length > 0) { 13 | var pid = this.empty.pop(); 14 | this.threads[pid] = thread; 15 | return pid; 16 | } else { 17 | return this.threads.push(thread) - 1; 18 | } 19 | } 20 | 21 | Threads.prototype.remove = function(pid) { 22 | this.empty.push(pid); 23 | this.threads[pid] = null; 24 | } 25 | 26 | Threads.prototype.count = function() { 27 | return this.threads.length - this.empty.length; 28 | } 29 | 30 | Threads.prototype.getThread = function(pid) { 31 | return this.threads[pid]; 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /libs/util/globalizer.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | module.exports.add = function(name, obj) { 7 | global[name] = obj; 8 | } 9 | 10 | module.exports.remove = function(name) { 11 | delete global[name]; 12 | } -------------------------------------------------------------------------------- /libs/util/numeric.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | module.exports.getByte = function(v) { 7 | n = parseInt(v, 10) & 0xff; 8 | if (n > 0x7F) { 9 | n = -((n & 0x7F) ^ 0x7F) - 1; 10 | } 11 | return n 12 | } 13 | 14 | module.exports.getInt = function(v) { 15 | n = parseInt(v, 10) & 0xffff; 16 | if (n > 0x7FFF) { 17 | n = -((n & 0x7FFF) ^ 0x7FFF) - 1; 18 | } 19 | return n 20 | } 21 | 22 | module.exports.getLong = function(bytes) { 23 | var l = 0; 24 | for(var i = 0; i < 8; i++) { 25 | l <<= 8; 26 | l ^= bytes[i] & 0xFF; 27 | } 28 | return l; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /libs/util/reader.js: -------------------------------------------------------------------------------- 1 | /* 2 | node-jvm 3 | Copyright (c) 2013 Yaroslav Gaponov 4 | */ 5 | 6 | var Reader = function(bytes, offset) { 7 | if (this instanceof Reader) { 8 | this.bytes = bytes; 9 | this.offset = offset || 0; 10 | } else { 11 | return new Reader(bytes, offset); 12 | } 13 | } 14 | 15 | Reader.prototype.read8 = function() { 16 | var data = this.bytes.readUInt8(this.offset); 17 | this.offset += 1; 18 | return data; 19 | } 20 | 21 | Reader.prototype.read16 = function() { 22 | var data = this.bytes.readUInt16BE(this.offset); 23 | this.offset += 2; 24 | return data; 25 | } 26 | 27 | Reader.prototype.read32 = function() { 28 | var data = this.bytes.readUInt32BE(this.offset); 29 | this.offset += 4; 30 | return data; 31 | } 32 | 33 | Reader.prototype.readString = function(length) { 34 | var data = this.bytes.toString(undefined, this.offset, this.offset + length) 35 | this.offset += length; 36 | return data; 37 | } 38 | 39 | Reader.prototype.readBytes = function(length) { 40 | var data = this.bytes.slice(this.offset, this.offset + length); 41 | this.offset += length; 42 | return data; 43 | } 44 | 45 | 46 | module.exports.create = function(bytes, offset) { 47 | return new Reader(bytes, offset); 48 | } 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-jvm", 3 | "version": "0.2.3", 4 | "description": "jvm", 5 | "main": "index.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "test": "grunt test" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/YaroslavGaponov/node-jvm.git" 15 | }, 16 | "keywords": [ 17 | "jvm", 18 | "java", 19 | "virtual", 20 | "machine" 21 | ], 22 | "dependencies": { 23 | "adm-zip": ">=0.4.11" 24 | }, 25 | "devDependencies": { 26 | "grunt": "~0.4.1", 27 | "grunt-mocha-test": "~0.7.0", 28 | "chai": "~1.8.0", 29 | "sinon": "~1.7.3", 30 | "sinon-chai": "~2.4.0", 31 | "grunt-node-webkit-builder": "~0.1.11" 32 | }, 33 | "engines": { 34 | "node": ">=8.11.0" 35 | }, 36 | "author": "Yaroslav Gaponov", 37 | "license": "MIT", 38 | "readmeFilename": "readme.md", 39 | "gitHead": "83c5cb707556be23a180c7bd62c6f20ad65b979a", 40 | "bugs": { 41 | "url": "https://github.com/YaroslavGaponov/node-jvm/issues" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | node-jvm [![Build Status](https://travis-ci.org/YaroslavGaponov/node-jvm.png?branch=master)](https://travis-ci.org/YaroslavGaponov/node-jvm) 2 | ======== 3 | 4 | 5 | ## Overview 6 | 7 | node-jvm - jvm in pure node.js 8 | 9 | 10 | ## Example 11 | 12 | ### java 13 | ```java 14 | public class Main { 15 | public static long fib(int n) { 16 | if (n <= 1) return n; 17 | return fib(n-1) + fib(n-2); 18 | } 19 | 20 | public static void main(String[] args) { 21 | if (args.length == 0) { 22 | System.out.print("help: java Main.class {Number}"); 23 | return; 24 | } 25 | 26 | int N = Integer.parseInt(args[0]); 27 | long start = System.currentTimeMillis(); 28 | System.out.format("Fibonacci from 1 to %s:\n", N); 29 | for (int i = 1; i <= N; i++) { 30 | System.out.println(i + ": " + fib(i)); 31 | } 32 | long stop = System.currentTimeMillis(); 33 | System.out.println("time: " + (stop - start) + "ms"); 34 | 35 | System.out.println("done."); 36 | } 37 | } 38 | ``` 39 | 40 | ### node.js 41 | ```javascript 42 | var JVM = require("node-jvm"); 43 | var jvm = new JVM(); 44 | jvm.setLogLevel(7); 45 | var entryPointClassName = jvm.loadJarFile("./Main.jar"); 46 | jvm.setEntryPointClassName(entryPointClassName); 47 | jvm.on("exit", function(code) { 48 | process.exit(code); 49 | }); 50 | jvm.run([15]); 51 | ``` 52 | 53 | ### build java files 54 | `cd examples/fibonacci; make` 55 | 56 | ### run jvm 57 | `./fibonacci.js` 58 | 59 | ### clean 60 | `make clean` 61 | 62 | ### output 63 | ``` 64 | Fibonacci from 1 to 15: 65 | 1: 1 66 | 2: 1 67 | 3: 2 68 | 4: 3 69 | 5: 5 70 | 6: 8 71 | 7: 13 72 | 8: 21 73 | 9: 34 74 | 10: 55 75 | 11: 89 76 | 12: 144 77 | 13: 233 78 | 14: 377 79 | 15: 610 80 | time: 106ms 81 | done. 82 | ``` 83 | 84 | ### other examples 85 | `cd examples/` 86 | 87 | ``` 88 | arrays - working with different types of arrays 89 | dogs - simple object-oriented programming 90 | fibonacci - recursion 91 | jsclass - java and javascript mix 92 | switcher - working with different switches 93 | cast - cast for different types 94 | ex - program exceptions 95 | ex2 - jvm exceptions 96 | idogs - working with interface 97 | static - working with static objects 98 | threads - multithreading 99 | ``` 100 | 101 | 102 | ## Developer 103 | 104 | Yaroslav Gaponov (yaroslav.gaponov -at - gmail.com) 105 | 106 | ## License 107 | 108 | The MIT License (MIT) 109 | 110 | Copyright (c) 2013 Yaroslav Gaponov 111 | 112 | Permission is hereby granted, free of charge, to any person obtaining a copy 113 | of this software and associated documentation files (the "Software"), to deal 114 | in the Software without restriction, including without limitation the rights 115 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 116 | copies of the Software, and to permit persons to whom the Software is 117 | furnished to do so, subject to the following conditions: 118 | 119 | The above copyright notice and this permission notice shall be included in 120 | all copies or substantial portions of the Software. 121 | 122 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 123 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 124 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 125 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 126 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 127 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 128 | THE SOFTWARE. 129 | -------------------------------------------------------------------------------- /test/_basic/Object.java: -------------------------------------------------------------------------------- 1 | package _basic; 2 | public class Object {} -------------------------------------------------------------------------------- /test/_static/Main.java: -------------------------------------------------------------------------------- 1 | package _static; 2 | public class Main { 3 | public static Nested o = new Nested(1); 4 | } -------------------------------------------------------------------------------- /test/_static/Nested.java: -------------------------------------------------------------------------------- 1 | package _static; 2 | public class Nested { 3 | private int number; 4 | 5 | public Nested(int number) { 6 | this.number = number; 7 | } 8 | 9 | public void setNumber(int number) { 10 | this.number = number; 11 | } 12 | 13 | public int getNumber() { 14 | return number; 15 | } 16 | } -------------------------------------------------------------------------------- /test/basic_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var expect = require('chai').expect; 4 | 5 | var child_process = require("child_process"); 6 | require('chai').should(); 7 | 8 | var JVM = require("../index"); 9 | var jvm = new JVM(); 10 | 11 | describe('Object', function () { 12 | before(function(done){ 13 | this.timeout(10000); 14 | child_process.exec("javac _basic/Object.java", {cwd : __dirname},function(err){ 15 | if (err) throw err; 16 | jvm.loadClassFile(__dirname + "/_basic/Object.class"); 17 | done(); 18 | }); 19 | }); 20 | 21 | describe("equals", function () { 22 | it("should return true for same instance", function () { 23 | var o = CLASSES.newObject("_basic/Object"); 24 | expect(o.equals(o)).to.be.true; 25 | }); 26 | 27 | it("should return false for different instances", function () { 28 | var o1 = CLASSES.newObject("_basic/Object"); 29 | var o2 = CLASSES.newObject("_basic/Object"); 30 | expect(o1.equals(o2)).to.be.false; 31 | }); 32 | }); 33 | 34 | describe("getClass", function () { 35 | it("return correct class object", function () { 36 | var o = CLASSES.newObject("_basic/Object"); 37 | expect(o.getClassName()).to.be.equal("_basic/Object"); 38 | }); 39 | }); 40 | 41 | describe("toString", function () { 42 | it("return correct class object", function () { 43 | var o = CLASSES.newObject("_basic/Object"); 44 | expect(o.toString()).to.be.equal("_basic/Object" + '@' + o.hashCode().toString(16)); 45 | }); 46 | }); 47 | 48 | describe("hashcode", function () { 49 | it("should return an int", function () { 50 | var o = CLASSES.newObject("_basic/Object"); 51 | expect(o.hashCode()).to.be.a('number'); 52 | expect(o.hashCode()).to.be.greaterThan(0); 53 | }); 54 | 55 | it("should be different for different instances", function () { 56 | var o1 = CLASSES.newObject("_basic/Object"); 57 | var o2 = CLASSES.newObject("_basic/Object"); 58 | expect(o1.hashCode()).not.to.be.equal(o2.hashCode()); 59 | }); 60 | }); 61 | }); -------------------------------------------------------------------------------- /test/static_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var expect = require('chai').expect; 4 | 5 | var child_process = require("child_process"); 6 | require('chai').should(); 7 | 8 | var JVM = require("../index"); 9 | var jvm = new JVM(); 10 | 11 | describe('Static', function () { 12 | before(function(done){ 13 | this.timeout(10000); 14 | child_process.exec("javac _static/Main.java _static/Nested.java", {cwd : __dirname},function(err){ 15 | if (err) throw err; 16 | jvm.loadClassFiles(__dirname + "/_static"); 17 | CLASSES.clinit(); 18 | done(); 19 | }); 20 | }); 21 | 22 | describe("equals", function () { 23 | it("should return true for default number", function () { 24 | var nested = CLASSES.getStaticField("_static/Main","o"); 25 | nested.getNumber.run([nested], function(number) { 26 | expect(number).to.be.equal(1); 27 | }); 28 | }); 29 | 30 | it("should return true for custom number", function () { 31 | var nested = CLASSES.getStaticField("_static/Main","o"); 32 | nested.setNumber.run([nested, 1000], function() { 33 | nested.getNumber.run([nested], function(number) { 34 | expect(number).to.be.equal(1000); 35 | }); 36 | }); 37 | }); 38 | }); 39 | 40 | }); --------------------------------------------------------------------------------