From ee080b93ef2d8cd38f90753d5d2c7a92159b9694 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Wed, 9 Jul 2014 01:07:14 -0700 Subject: [PATCH] fix nasty bug in sipush --- classes.js | 76 ++++++++++++++++-------------------------------------- frame.js | 24 ++++++++++++----- 2 files changed, 39 insertions(+), 61 deletions(-) diff --git a/classes.js b/classes.js index 2c9786f8..70599916 100644 --- a/classes.js +++ b/classes.js @@ -85,14 +85,14 @@ Classes.prototype.getEntryPoint = function(className, methodName) { Classes.prototype.initClass = function(className) { var clinit = this.getStaticMethod(className, "", "()V"); - if (clinit instanceof Frame) { - SCHEDULER.sync(function() { - LOG.debug("call " + className + ". ..."); - clinit.run([], function() { - LOG.debug("call " + className + ". ... done"); - }); + if (!clinit) + return; + SCHEDULER.sync(function() { + LOG.debug("call " + className + ". ..."); + clinit.run([], function() { + LOG.debug("call " + className + ". ... done"); }); - } + }); } Classes.prototype.getClass = function(className, initialize) { @@ -117,16 +117,18 @@ Classes.prototype.setStaticField = function(className, fieldName, value) { this.getClass(className, true).staticFields[fieldName] = value; } -Classes.prototype.getStaticMethod = function(className, methodName, signature) { - var ca = this.getClass(className, true); +Classes.prototype.getMethod = function(className, methodName, signature, staticFlag) { + // Only force initialization when accessing a static method. + var ca = this.getClass(className, staticFlag); if (ca instanceof ClassArea) { var methods = ca.getMethods(); var cp = ca.getConstantPool(); - for(var i=0; i$(Ljava/lang/String;)V"]; + var ctor = this.getMethod(className, "", "(Ljava/lang/String;)V"); ctor.setPid(self._pid); ctor.run([ex, message], function () { self._throw(ex); @@ -105,7 +105,7 @@ Frame.prototype.run = function(args, done) { var step = function() { SCHEDULER.tick(self._pid, function() { var opCode = self._read8(); - console.log(OPCODES.toString(opCode), self._stack.length); + console.log(self._ip - 1, OPCODES.toString(opCode), self._stack.length); switch (opCode) { case OPCODES.return: return done(); @@ -220,6 +220,7 @@ Frame.prototype.iconst_5 = function(done) { Frame.prototype.sipush = function(done) { this._stack.push(this._read16()); + return done(); } Frame.prototype.bipush = function(done) { @@ -1408,6 +1409,9 @@ Frame.prototype.getfield = function(done) { if (!obj) { return this._newException("java/lang/NullPointerException", done); } + if (!(fieldName in obj)) { + return this._newException("java/lang/VirtualMachineError", done); + } this._stack.push(obj[fieldName]); return done(); } @@ -1424,7 +1428,9 @@ Frame.prototype.getstatic = function(done) { var idx = this._read16(); var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes; var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; + console.log("XXXXXXXXXXXX BEGIN GETSTATIC XXXXXXXXXXXXX", className, fieldName); this._stack.push(CLASSES.getStaticField(className, fieldName)); + console.log("XXXXXXXXXXXX DONE GETSTATIC XXXXXXXXXXXXX", className, fieldName); return done(); } @@ -1432,6 +1438,7 @@ Frame.prototype.putstatic = function(done) { var idx = this._read16(); var className = this._cp[this._cp[this._cp[idx].class_index].name_index].bytes; var fieldName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; + console.log(className, fieldName, CLASSES.getStaticField(className, fieldName)); CLASSES.setStaticField(className, fieldName, this._stack.pop()); return done(); } @@ -1454,9 +1461,9 @@ Frame.prototype.invokestatic = function(done) { args.unshift(this._stack.pop()); } } - + var method = CLASSES.getStaticMethod(className, methodName, signature); - + if (method instanceof Frame) { method.setPid(self._pid); method.run(args, function(res) { @@ -1484,6 +1491,8 @@ Frame.prototype.invokevirtual = function(done) { var methodName = this._cp[this._cp[this._cp[idx].name_and_type_index].name_index].bytes; var signature = Signature.parse(this._cp[this._cp[this._cp[idx].name_and_type_index].signature_index].bytes); + console.log("invokevirtual", className, methodName, signature); + var args = []; for (var i=0; i