Make synthetic methods use the MethodInfo constructor.

This commit is contained in:
Marcus Cavanaugh 2014-10-09 16:20:18 -07:00
Родитель 29e57f37dd
Коммит 527e65a695
3 изменённых файлов: 55 добавлений и 31 удалений

Просмотреть файл

@ -34,26 +34,44 @@ function missingNativeImpl(key, ctx, stack) {
console.error("Attempted to invoke missing native:", key);
}
function MethodInfo(m, classInfo, constantPool) {
this.classInfo = classInfo;
this.name = constantPool[m.name_index].bytes;
this.signature = constantPool[m.signature_index].bytes;
this.attributes = m.attributes;
/**
* Required params:
* - name
* - signature
* - classInfo
*
* Optional params:
* - attributes (defaults to [])
* - code (if not provided, pulls from attributes)
* - isNative, isPublic, isStatic, isSynchronized
*/
function MethodInfo(opts) {
this.name = opts.name;
this.signature = opts.signature;
this.classInfo = opts.classInfo;
this.attributes = opts.attributes || [];
for (var i = 0; i < this.attributes.length; i++) {
var a = this.attributes[i];
if (a.info.type === ATTRIBUTE_TYPES.Code) {
this.code = new Uint8Array(a.info.code);
this.exception_table = a.info.exception_table;
this.max_locals = a.info.max_locals;
break;
// Use code if provided, otherwise search for the code within attributes.
if (opts.code) {
this.code = opts.code;
this.exception_table = [];
this.max_locals = undefined; // Unused for now.
} else {
for (var i = 0; i < this.attributes.length; i++) {
var a = this.attributes[i];
if (a.info.type === ATTRIBUTE_TYPES.Code) {
this.code = new Uint8Array(a.info.code);
this.exception_table = a.info.exception_table;
this.max_locals = a.info.max_locals;
break;
}
}
}
this.isNative = ACCESS_FLAGS.isNative(m.access_flags);
this.isPublic = ACCESS_FLAGS.isPublic(m.access_flags);
this.isStatic = ACCESS_FLAGS.isStatic(m.access_flags);
this.isSynchronized = ACCESS_FLAGS.isSynchronized(m.access_flags);
this.isNative = opts.isNative;
this.isPublic = opts.isPublic;
this.isStatic = opts.isStatic;
this.isSynchronized = opts.isSynchronized;
this.key = (this.isStatic ? "S." : "I.") + this.name + "." + this.signature;
this.implKey = this.classInfo.className + "." + this.name + "." + this.signature;
@ -110,7 +128,16 @@ var ClassInfo = function(classBytes) {
this.methods = [];
classImage.methods.forEach(function(m) {
self.methods.push(new MethodInfo(m, self, cp));
self.methods.push(new MethodInfo({
name: cp[m.name_index].bytes,
signature: cp[m.signature_index].bytes,
classInfo: self,
attributes: m.attributes,
isNative: ACCESS_FLAGS.isNative(m.access_flags),
isPublic: ACCESS_FLAGS.isPublic(m.access_flags),
isStatic: ACCESS_FLAGS.isStatic(m.access_flags),
isSynchronized: ACCESS_FLAGS.isSynchronized(m.access_flags)
}));
});
var classes = this.classes = [];

Просмотреть файл

@ -38,7 +38,7 @@ Context.prototype.pushClassInitFrame = function(classInfo) {
if (this.runtime.initialized[classInfo.className])
return;
classInfo.thread = this.thread;
var syntheticMethod = {
var syntheticMethod = new MethodInfo({
name: "ClassInitSynthetic",
signature: "()V",
classInfo: {
@ -69,9 +69,8 @@ Context.prototype.pushClassInitFrame = function(classInfo) {
0xb7, 0x00, 0x07, // invokespecial <idx=7>
0xc3, // monitorexit
0xb1, // return
]),
exception_table: [],
};
])
});
this.current().stack.push(classInfo.getClassObject(this));
this.pushFrame(syntheticMethod, 1);
}
@ -80,7 +79,7 @@ Context.prototype.raiseException = function(className, message) {
if (!message)
message = "";
message = "" + message;
var syntheticMethod = {
var syntheticMethod = new MethodInfo({
name: "RaiseExceptionSynthetic",
signature: "()V",
classInfo: {
@ -105,9 +104,8 @@ Context.prototype.raiseException = function(className, message) {
0x12, 0x03, // ldc <idx=2>
0xb7, 0x00, 0x05, // invokespecial <idx=5>
0xbf // athrow
]),
exception_table: [],
};
])
});
this.pushFrame(syntheticMethod, 0);
}

Просмотреть файл

@ -269,7 +269,7 @@ Native["java/lang/Class.forName.(Ljava/lang/String;)Ljava/lang/Class;"] = functi
Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack) {
var classObject = stack.pop();
var className = classObject.vmClass.className;
var syntheticMethod = {
var syntheticMethod = new MethodInfo({
name: "ClassNewInstanceSynthetic",
signature: "()Ljava/lang/Object;",
classInfo: {
@ -292,7 +292,7 @@ Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack
0xb7, 0x00, 0x03, // invokespecial <idx=3>
0xb0 // areturn
]),
};
});
ctx.pushFrame(syntheticMethod, 0);
throw VM.Yield;
};
@ -476,7 +476,7 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
var ctx = new Context(ctx.runtime);
ctx.thread = thread;
var syntheticMethod = {
var syntheticMethod = new MethodInfo({
name: "ThreadStart0Synthetic",
signature: "()V",
classInfo: {
@ -503,9 +503,8 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
0xb6, 0x00, 0x01, // invokespecial <idx=1>
0xb7, 0x00, 0x07, // invokespecial <idx=7>
0xb1, // return
]),
exception_table: [],
};
])
});
ctx.frames.push(new Frame(syntheticMethod, [ thread ], 0));
ctx.start();