diff --git a/jit/baseline.ts b/jit/baseline.ts index 9a5d3077..27702471 100644 --- a/jit/baseline.ts +++ b/jit/baseline.ts @@ -861,7 +861,7 @@ module J2ME { object = this.pop(Kind.Reference); if (opcode === Bytecodes.INVOKESPECIAL) { args.unshift(object); - call = classConstant(methodInfo.classInfo) + "." + methodInfo.staticName + ".call(" + args.join(",") + ")"; + call = classConstant(methodInfo.classInfo) + ".m(" + methodInfo.index + ").call(" + args.join(",") + ")"; } else if (opcode === Bytecodes.INVOKEVIRTUAL) { call = object + "." + methodInfo.virtualName + "(" + args.join(",") + ")"; } else if (opcode === Bytecodes.INVOKEINTERFACE) { @@ -870,7 +870,7 @@ module J2ME { assert(false); } } else { - call = classConstant(methodInfo.classInfo) + "." + methodInfo.staticName + "(" + args.join(",") + ")"; + call = classConstant(methodInfo.classInfo) + ".m(" + methodInfo.index + ")" + "(" + args.join(",") + ")"; } if (methodInfo.implKey in inlineMethods) { emitDebugInfoComments && this.blockEmitter.writeLn("// Inlining: " + methodInfo.implKey); diff --git a/vm/parser.ts b/vm/parser.ts index 439a5e2d..4b951def 100644 --- a/vm/parser.ts +++ b/vm/parser.ts @@ -617,7 +617,6 @@ module J2ME { vTableIndex: number; - private _staticName: string; private _virtualName: string; private _mangledName: string; private _mangledClassAndMethodName: string; @@ -675,10 +674,6 @@ module J2ME { return undefined; } - get staticName() { - return this._staticName || (this._staticName = "m" + this.index); - } - get mangledName() { return this._mangledName || (this._mangledName = mangleMethod(this)); } diff --git a/vm/runtime.ts b/vm/runtime.ts index 85f1ba5e..8cd4aacb 100644 --- a/vm/runtime.ts +++ b/vm/runtime.ts @@ -833,6 +833,16 @@ module J2ME { isArrayKlass: boolean; elementKlass: Klass; + + /** + * Links class method. + */ + m(index: number): Function; + + /** + * Linked class methods. + */ + methods: Function[]; } export class RuntimeKlass { @@ -1454,7 +1464,7 @@ module J2ME { fn = tracingWrapper(fn, methodInfo, methodType); } - klass[methodInfo.staticName] = methodInfo.fn = fn; + klass.methods[methodInfo.index] = methodInfo.fn = fn; if (!methodInfo.isStatic && methodInfo.virtualName) { release || assert(klass.prototype.hasOwnProperty(methodInfo.virtualName)); @@ -1605,6 +1615,17 @@ module J2ME { } } + function klassMethodLink(index: number) { + var klass: Klass = this; + var fn = klass.methods[index]; + if (fn) { + return fn; + } + linkKlassMethod(klass, klass.classInfo.getMethodByIndex(index)); + release || assert(klass.methods[index], "Method should be linked now."); + return klass.methods[index]; + } + export function extendKlass(classInfo: ClassInfo, klass: Klass, superKlass: Klass) { klass.superKlass = superKlass; if (superKlass) { @@ -1624,7 +1645,10 @@ module J2ME { klass.prototype.klass = klass; initializeKlassTables(klass); initializeKlassVirtualMethodTrampolines(classInfo, klass); - initializeKlassMethodTrampolines(classInfo, klass); + + // Method linking. + klass.m = klassMethodLink; + klass.methods = new Array(classInfo.getMethodCount()); } /**