зеркало из https://github.com/mozilla/pluotsorbet.git
fix nasty bug in sipush
This commit is contained in:
Родитель
1be8b65ee4
Коммит
ee080b93ef
76
classes.js
76
classes.js
|
@ -85,14 +85,14 @@ Classes.prototype.getEntryPoint = function(className, methodName) {
|
|||
|
||||
Classes.prototype.initClass = function(className) {
|
||||
var clinit = this.getStaticMethod(className, "<clinit>", "()V");
|
||||
if (clinit instanceof Frame) {
|
||||
SCHEDULER.sync(function() {
|
||||
LOG.debug("call " + className + ".<clinit> ...");
|
||||
clinit.run([], function() {
|
||||
LOG.debug("call " + className + ".<clinit> ... done");
|
||||
});
|
||||
if (!clinit)
|
||||
return;
|
||||
SCHEDULER.sync(function() {
|
||||
LOG.debug("call " + className + ".<clinit> ...");
|
||||
clinit.run([], function() {
|
||||
LOG.debug("call " + className + ".<clinit> ... 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<methods.length; i++)
|
||||
if (ACCESS_FLAGS.isStatic(methods[i].access_flags))
|
||||
for(var i=0; i<methods.length; i++) {
|
||||
if (ACCESS_FLAGS.isStatic(methods[i].access_flags) === !!staticFlag)
|
||||
if (cp[methods[i].name_index].bytes === methodName)
|
||||
if (signature.toString() === cp[methods[i].signature_index].bytes)
|
||||
return new Frame(ca, methods[i]);
|
||||
}
|
||||
} else {
|
||||
if (methodName in ca) {
|
||||
return ca[methodName];
|
||||
|
@ -134,48 +136,14 @@ Classes.prototype.getStaticMethod = function(className, methodName, signature) {
|
|||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Classes.prototype.getMethod = function(className, methodName, signature) {
|
||||
// We won't get here without a call to newObject, so no need to force
|
||||
// class initialization.
|
||||
var ca = this.getClass(className, false);
|
||||
if (ca instanceof ClassArea) {
|
||||
var methods = ca.getMethods();
|
||||
var cp = ca.getConstantPool();
|
||||
for(var i=0; i<methods.length; i++)
|
||||
if (!ACCESS_FLAGS.isStatic(methods[i].access_flags))
|
||||
if (cp[methods[i].name_index].bytes === methodName)
|
||||
if (signature.toString() === cp[methods[i].signature_index].bytes)
|
||||
return new Frame(ca, methods[i]);
|
||||
} else {
|
||||
var o = new ca();
|
||||
if (methodName in o) {
|
||||
return o[methodName];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Classes.prototype.newObject = function(className) {
|
||||
var ca = this.getClass(className, true);
|
||||
var ctor = function() {};
|
||||
var superClassName = ca.getSuperClassName();
|
||||
if (superClassName)
|
||||
ctor.prototype = this.newObject(superClassName);
|
||||
var o = new ctor();
|
||||
|
||||
var cp = ca.getConstantPool();
|
||||
|
||||
ca.getFields().forEach(function(field) {
|
||||
var fieldName = cp[field.name_index].bytes;
|
||||
o[fieldName] = null;
|
||||
});
|
||||
|
||||
ca.getMethods().forEach(function(method) {
|
||||
var methodName = cp[method.name_index].bytes;
|
||||
var signature = cp[method.signature_index].bytes;
|
||||
o[methodName + "$" + signature] = new Frame(ca, method);
|
||||
});
|
||||
|
||||
return o;
|
||||
Classes.prototype.getStaticMethod = function(className, methodName, signature) {
|
||||
return this.getMethod(className, methodName, signature, true);
|
||||
}
|
||||
|
||||
Classes.prototype.newObject = function(className) {
|
||||
// Force initialization of the class (if not already done).
|
||||
this.getClass(className, true);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
24
frame.js
24
frame.js
|
@ -80,10 +80,10 @@ Frame.prototype._throw = function(ex) {
|
|||
}
|
||||
|
||||
Frame.prototype._newException = function(className, message) {
|
||||
var done = arguments[arguments.length-1];
|
||||
var self = this;
|
||||
var ex = CLASSES.newObject(className);
|
||||
var done = arguments[arguments.length-1];
|
||||
var ctor = ex["<init>$(Ljava/lang/String;)V"];
|
||||
var ctor = this.getMethod(className, "<init>", "(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<signature.IN.length; i++) {
|
||||
if (!signature.IN[i].isArray && ["long", "double"].indexOf(signature.IN[i].type) !== -1) {
|
||||
|
@ -1497,7 +1506,7 @@ Frame.prototype.invokevirtual = function(done) {
|
|||
|
||||
var instance = this._stack.pop();
|
||||
var method = CLASSES.getMethod(className, methodName, signature);
|
||||
|
||||
|
||||
if (method instanceof Frame) {
|
||||
args.unshift(instance);
|
||||
method.setPid(self._pid);
|
||||
|
@ -1525,6 +1534,8 @@ Frame.prototype.invokespecial = 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("invokespecial", className, methodName, signature);
|
||||
|
||||
var args = [];
|
||||
for (var i=0; i<signature.IN.length; i++) {
|
||||
if (!signature.IN[i].isArray && ["long", "double"].indexOf(signature.IN[i].type) !== -1) {
|
||||
|
@ -1535,7 +1546,6 @@ Frame.prototype.invokespecial = function(done) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
var instance = this._stack.pop();
|
||||
var ctor = CLASSES.getMethod(className, methodName, signature);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче