зеркало из https://github.com/mozilla/pluotsorbet.git
Make synthetic methods use the MethodInfo constructor.
This commit is contained in:
Родитель
29e57f37dd
Коммит
527e65a695
61
classinfo.js
61
classinfo.js
|
@ -34,26 +34,44 @@ function missingNativeImpl(key, ctx, stack) {
|
||||||
console.error("Attempted to invoke missing native:", key);
|
console.error("Attempted to invoke missing native:", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MethodInfo(m, classInfo, constantPool) {
|
/**
|
||||||
this.classInfo = classInfo;
|
* Required params:
|
||||||
this.name = constantPool[m.name_index].bytes;
|
* - name
|
||||||
this.signature = constantPool[m.signature_index].bytes;
|
* - signature
|
||||||
this.attributes = m.attributes;
|
* - 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++) {
|
// Use code if provided, otherwise search for the code within attributes.
|
||||||
var a = this.attributes[i];
|
if (opts.code) {
|
||||||
if (a.info.type === ATTRIBUTE_TYPES.Code) {
|
this.code = opts.code;
|
||||||
this.code = new Uint8Array(a.info.code);
|
this.exception_table = [];
|
||||||
this.exception_table = a.info.exception_table;
|
this.max_locals = undefined; // Unused for now.
|
||||||
this.max_locals = a.info.max_locals;
|
} else {
|
||||||
break;
|
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.isNative = opts.isNative;
|
||||||
this.isPublic = ACCESS_FLAGS.isPublic(m.access_flags);
|
this.isPublic = opts.isPublic;
|
||||||
this.isStatic = ACCESS_FLAGS.isStatic(m.access_flags);
|
this.isStatic = opts.isStatic;
|
||||||
this.isSynchronized = ACCESS_FLAGS.isSynchronized(m.access_flags);
|
this.isSynchronized = opts.isSynchronized;
|
||||||
this.key = (this.isStatic ? "S." : "I.") + this.name + "." + this.signature;
|
this.key = (this.isStatic ? "S." : "I.") + this.name + "." + this.signature;
|
||||||
this.implKey = this.classInfo.className + "." + this.name + "." + this.signature;
|
this.implKey = this.classInfo.className + "." + this.name + "." + this.signature;
|
||||||
|
|
||||||
|
@ -110,7 +128,16 @@ var ClassInfo = function(classBytes) {
|
||||||
|
|
||||||
this.methods = [];
|
this.methods = [];
|
||||||
classImage.methods.forEach(function(m) {
|
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 = [];
|
var classes = this.classes = [];
|
||||||
|
|
14
context.js
14
context.js
|
@ -38,7 +38,7 @@ Context.prototype.pushClassInitFrame = function(classInfo) {
|
||||||
if (this.runtime.initialized[classInfo.className])
|
if (this.runtime.initialized[classInfo.className])
|
||||||
return;
|
return;
|
||||||
classInfo.thread = this.thread;
|
classInfo.thread = this.thread;
|
||||||
var syntheticMethod = {
|
var syntheticMethod = new MethodInfo({
|
||||||
name: "ClassInitSynthetic",
|
name: "ClassInitSynthetic",
|
||||||
signature: "()V",
|
signature: "()V",
|
||||||
classInfo: {
|
classInfo: {
|
||||||
|
@ -69,9 +69,8 @@ Context.prototype.pushClassInitFrame = function(classInfo) {
|
||||||
0xb7, 0x00, 0x07, // invokespecial <idx=7>
|
0xb7, 0x00, 0x07, // invokespecial <idx=7>
|
||||||
0xc3, // monitorexit
|
0xc3, // monitorexit
|
||||||
0xb1, // return
|
0xb1, // return
|
||||||
]),
|
])
|
||||||
exception_table: [],
|
});
|
||||||
};
|
|
||||||
this.current().stack.push(classInfo.getClassObject(this));
|
this.current().stack.push(classInfo.getClassObject(this));
|
||||||
this.pushFrame(syntheticMethod, 1);
|
this.pushFrame(syntheticMethod, 1);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +79,7 @@ Context.prototype.raiseException = function(className, message) {
|
||||||
if (!message)
|
if (!message)
|
||||||
message = "";
|
message = "";
|
||||||
message = "" + message;
|
message = "" + message;
|
||||||
var syntheticMethod = {
|
var syntheticMethod = new MethodInfo({
|
||||||
name: "RaiseExceptionSynthetic",
|
name: "RaiseExceptionSynthetic",
|
||||||
signature: "()V",
|
signature: "()V",
|
||||||
classInfo: {
|
classInfo: {
|
||||||
|
@ -105,9 +104,8 @@ Context.prototype.raiseException = function(className, message) {
|
||||||
0x12, 0x03, // ldc <idx=2>
|
0x12, 0x03, // ldc <idx=2>
|
||||||
0xb7, 0x00, 0x05, // invokespecial <idx=5>
|
0xb7, 0x00, 0x05, // invokespecial <idx=5>
|
||||||
0xbf // athrow
|
0xbf // athrow
|
||||||
]),
|
])
|
||||||
exception_table: [],
|
});
|
||||||
};
|
|
||||||
this.pushFrame(syntheticMethod, 0);
|
this.pushFrame(syntheticMethod, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
native.js
11
native.js
|
@ -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) {
|
Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack) {
|
||||||
var classObject = stack.pop();
|
var classObject = stack.pop();
|
||||||
var className = classObject.vmClass.className;
|
var className = classObject.vmClass.className;
|
||||||
var syntheticMethod = {
|
var syntheticMethod = new MethodInfo({
|
||||||
name: "ClassNewInstanceSynthetic",
|
name: "ClassNewInstanceSynthetic",
|
||||||
signature: "()Ljava/lang/Object;",
|
signature: "()Ljava/lang/Object;",
|
||||||
classInfo: {
|
classInfo: {
|
||||||
|
@ -292,7 +292,7 @@ Native["java/lang/Class.newInstance.()Ljava/lang/Object;"] = function(ctx, stack
|
||||||
0xb7, 0x00, 0x03, // invokespecial <idx=3>
|
0xb7, 0x00, 0x03, // invokespecial <idx=3>
|
||||||
0xb0 // areturn
|
0xb0 // areturn
|
||||||
]),
|
]),
|
||||||
};
|
});
|
||||||
ctx.pushFrame(syntheticMethod, 0);
|
ctx.pushFrame(syntheticMethod, 0);
|
||||||
throw VM.Yield;
|
throw VM.Yield;
|
||||||
};
|
};
|
||||||
|
@ -476,7 +476,7 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
|
||||||
var ctx = new Context(ctx.runtime);
|
var ctx = new Context(ctx.runtime);
|
||||||
ctx.thread = thread;
|
ctx.thread = thread;
|
||||||
|
|
||||||
var syntheticMethod = {
|
var syntheticMethod = new MethodInfo({
|
||||||
name: "ThreadStart0Synthetic",
|
name: "ThreadStart0Synthetic",
|
||||||
signature: "()V",
|
signature: "()V",
|
||||||
classInfo: {
|
classInfo: {
|
||||||
|
@ -503,9 +503,8 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) {
|
||||||
0xb6, 0x00, 0x01, // invokespecial <idx=1>
|
0xb6, 0x00, 0x01, // invokespecial <idx=1>
|
||||||
0xb7, 0x00, 0x07, // invokespecial <idx=7>
|
0xb7, 0x00, 0x07, // invokespecial <idx=7>
|
||||||
0xb1, // return
|
0xb1, // return
|
||||||
]),
|
])
|
||||||
exception_table: [],
|
});
|
||||||
};
|
|
||||||
|
|
||||||
ctx.frames.push(new Frame(syntheticMethod, [ thread ], 0));
|
ctx.frames.push(new Frame(syntheticMethod, [ thread ], 0));
|
||||||
ctx.start();
|
ctx.start();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче