зеркало из https://github.com/mozilla/pluotsorbet.git
Merge pull request #409 from mcav/alternate-info
Move alternateImpl detection into MethodInfo constructor.
This commit is contained in:
Коммит
dd4f995dbb
22
classinfo.js
22
classinfo.js
|
@ -30,6 +30,10 @@ FieldInfo.prototype.toString = function() {
|
|||
return "[field " + this.name + "]";
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -50,10 +54,22 @@ function MethodInfo(m, classInfo, constantPool) {
|
|||
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.key = (this.isStatic ? "S." : "I.") + this.name + "." + this.signature;
|
||||
this.implKey = this.classInfo.className + "." + this.name + "." + this.signature;
|
||||
|
||||
this.alternateImpl = (this.isNative ? Native :
|
||||
Override.hasMethod(this) ? Override :
|
||||
null);
|
||||
if (this.isNative) {
|
||||
if (this.implKey in Native) {
|
||||
this.alternateImpl = Native[this.implKey];
|
||||
} else {
|
||||
// Some Native MethodInfos are constructed but never called;
|
||||
// that's fine, unless we actually try to call them.
|
||||
this.alternateImpl = missingNativeImpl.bind(null, this.implKey);
|
||||
}
|
||||
} else if (this.implKey in Override) {
|
||||
this.alternateImpl = Override[this.implKey];
|
||||
} else {
|
||||
this.alternateImpl = null;
|
||||
}
|
||||
}
|
||||
|
||||
var ClassInfo = function(classBytes) {
|
||||
|
|
|
@ -10,12 +10,8 @@ var Instrument = {
|
|||
profiling: false,
|
||||
profile: null,
|
||||
|
||||
getKey: function(methodInfo) {
|
||||
return methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
|
||||
},
|
||||
|
||||
callEnterHooks: function(methodInfo, caller, callee) {
|
||||
var key = this.getKey(methodInfo);
|
||||
var key = methodInfo.implKey;
|
||||
if (Instrument.enter[key]) {
|
||||
Instrument.enter[key](caller, callee);
|
||||
}
|
||||
|
@ -36,7 +32,7 @@ var Instrument = {
|
|||
},
|
||||
|
||||
callExitHooks: function(methodInfo, caller, callee) {
|
||||
var key = this.getKey(methodInfo);
|
||||
var key = methodInfo.implKey;
|
||||
|
||||
if (this.profiling) {
|
||||
var now = performance.now();
|
||||
|
@ -101,16 +97,15 @@ var Instrument = {
|
|||
this.profiling = false;
|
||||
},
|
||||
|
||||
measure: function(Alt, ctx, methodInfo) {
|
||||
measure: function(alternateImpl, ctx, methodInfo) {
|
||||
if (this.profiling) {
|
||||
var then = performance.now();
|
||||
Alt.invoke(ctx, methodInfo);
|
||||
var key = this.getKey(methodInfo);
|
||||
alternateImpl.call(null, ctx, ctx.current().stack);
|
||||
var methodProfileData = this.profile[key] || (this.profile[key] = { count: 0, cost: 0 });
|
||||
methodProfileData.count++;
|
||||
methodProfileData.cost += performance.now() - then;
|
||||
} else {
|
||||
Alt.invoke(ctx, methodInfo);
|
||||
alternateImpl.call(null, ctx, ctx.current().stack);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
12
native.js
12
native.js
|
@ -5,18 +5,6 @@
|
|||
|
||||
var Native = {};
|
||||
|
||||
Native.invoke = function(ctx, methodInfo) {
|
||||
if (!methodInfo.native) {
|
||||
var key = methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
|
||||
methodInfo.native = Native[key];
|
||||
if (!methodInfo.native) {
|
||||
console.error("Missing native: " + key);
|
||||
ctx.raiseExceptionAndYield("java/lang/RuntimeException", key + " not found");
|
||||
}
|
||||
}
|
||||
methodInfo.native.call(null, ctx, ctx.current().stack);
|
||||
}
|
||||
|
||||
Native["java/lang/System.arraycopy.(Ljava/lang/Object;ILjava/lang/Object;II)V"] = function(ctx, stack) {
|
||||
var length = stack.pop(), dstOffset = stack.pop(), dst = stack.pop(), srcOffset = stack.pop(), src = stack.pop();
|
||||
if (!src || !dst)
|
||||
|
|
20
override.js
20
override.js
|
@ -5,26 +5,6 @@
|
|||
|
||||
var Override = {};
|
||||
|
||||
Override.getKey = function(methodInfo) {
|
||||
return methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
|
||||
}
|
||||
|
||||
Override.hasMethod = function(methodInfo) {
|
||||
return ("override" in methodInfo || Override.getKey(methodInfo) in Override);
|
||||
}
|
||||
|
||||
Override.invoke = function(ctx, methodInfo) {
|
||||
if (!methodInfo.override) {
|
||||
var key = Override.getKey(methodInfo);
|
||||
methodInfo.override = Override[key];
|
||||
if (!methodInfo.override) {
|
||||
console.error("Missing override: " + key);
|
||||
ctx.raiseExceptionAndYield("java/lang/RuntimeException", key + " not found");
|
||||
}
|
||||
}
|
||||
methodInfo.override.call(null, ctx, ctx.current().stack);
|
||||
}
|
||||
|
||||
Override["com/ibm/oti/connection/file/Connection.decode.(Ljava/lang/String;)Ljava/lang/String;"] = function(ctx, stack) {
|
||||
var string = util.fromJavaString(stack.pop());
|
||||
stack.push(ctx.newString(decodeURIComponent(string)));
|
||||
|
|
4
vm.js
4
vm.js
|
@ -1040,10 +1040,6 @@ VM.execute = function(ctx) {
|
|||
case OPCODES.invokevirtual:
|
||||
case OPCODES.invokeinterface:
|
||||
if (methodInfo.classInfo != obj.class) {
|
||||
if (!methodInfo.key) {
|
||||
methodInfo.key = "I." + methodInfo.name + "." + methodInfo.signature;
|
||||
}
|
||||
|
||||
// Check if the method is already in the virtual method cache
|
||||
if (obj.class.vmc[methodInfo.key]) {
|
||||
methodInfo = obj.class.vmc[methodInfo.key];
|
||||
|
|
Загрузка…
Ссылка в новой задаче