From 1146835d77a99155e84105a8c71b1b5869c3ea10 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 30 Sep 2014 17:23:24 -0700 Subject: [PATCH] Don't create a fake caller frame for synthetic methods --- context.js | 15 +++++++++------ frame.js | 12 +++++------- jvm.js | 37 ++++++++++++++++--------------------- native.js | 10 +++++----- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/context.js b/context.js index b716df77..f09edb82 100644 --- a/context.js +++ b/context.js @@ -115,7 +115,7 @@ Context.prototype.raiseExceptionAndYield = function(className, message) { Context.prototype.execute = function(stopFrame) { Instrument.callResumeHooks(this.current()); - while (this.current() !== stopFrame) { + do { try { VM.execute(this); } catch (e) { @@ -130,16 +130,13 @@ Context.prototype.execute = function(stopFrame) { throw e; } } - } + } while (this.current() !== stopFrame); } Context.prototype.start = function(stopFrame) { - if (this.current() === stopFrame) { - this.kill(); - return; - } var ctx = this; ctx.stopFrame = stopFrame; + window.setZeroTimeout(function() { Instrument.callResumeHooks(ctx.current()); try { @@ -157,6 +154,12 @@ Context.prototype.start = function(stopFrame) { } } Instrument.callPauseHooks(ctx.current()); + + if (ctx.current() === stopFrame) { + ctx.kill(); + return; + } + ctx.start(stopFrame); }); } diff --git a/frame.js b/frame.js index 00185418..6404b30b 100644 --- a/frame.js +++ b/frame.js @@ -33,12 +33,10 @@ Array.prototype.popType = function(signature) { } var Frame = function(methodInfo, locals, localsBase) { - if (methodInfo) { - this.methodInfo = methodInfo; - this.cp = methodInfo.classInfo.constant_pool; - this.code = methodInfo.code; - this.ip = 0; - } + this.methodInfo = methodInfo; + this.cp = methodInfo.classInfo.constant_pool; + this.code = methodInfo.code; + this.ip = 0; this.stack = []; this.locals = locals; this.localsBase = localsBase; @@ -50,7 +48,7 @@ var Frame = function(methodInfo, locals, localsBase) { // on the stack, while stack.read(2) returns the one underneath it. this.stack.read = function(i) { return this[this.length - i] }; - Object.seal(this) + Object.seal(this); } Frame.prototype.getLocal = function(idx) { diff --git a/jvm.js b/jvm.js index 68d166d1..27e90942 100644 --- a/jvm.js +++ b/jvm.js @@ -34,22 +34,18 @@ JVM.prototype.startIsolate0 = function(className, args) { var isolate = ctx.newObject(com_sun_cldc_isolate_Isolate); isolate.id = util.id(); - var caller = new Frame(); - ctx.frames.push(caller); - var array = ctx.newArray("[Ljava/lang/String;", args.length); for (var n = 0; n < args.length; ++n) array[n] = args[n] ? ctx.newString(args[n]) : null; - caller.stack.push(isolate); - caller.stack.push(ctx.newString(className.replace(/\./g, "/"))); - caller.stack.push(array); - ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I..(Ljava/lang/String;[Ljava/lang/String;)V"), 3); - ctx.execute(caller); + var synthFrame1 = new Frame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I..(Ljava/lang/String;[Ljava/lang/String;)V"), + [ isolate, ctx.newString(className.replace(/\./g, "/")), array ], 0); + ctx.frames.push(synthFrame1); + ctx.execute(synthFrame1); - caller.stack.push(isolate); - ctx.pushFrame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I.start.()V"), 1); - ctx.start(caller); + var synthFrame2 = new Frame(CLASSES.getMethod(com_sun_cldc_isolate_Isolate, "I.start.()V"), [ isolate ], 0); + ctx.frames.push(synthFrame2); + ctx.start(synthFrame2); } JVM.prototype.startIsolate = function(isolate) { @@ -75,21 +71,20 @@ JVM.prototype.startIsolate = function(isolate) { if (!entryPoint) throw new Error("Could not find main method in class " + mainName); - var caller = new Frame(); - ctx.frames.push(caller); - ctx.thread = runtime.mainThread = ctx.newObject(CLASSES.java_lang_Thread); ctx.thread.pid = util.id(); ctx.thread.alive = true; - caller.stack.push(runtime.mainThread); - caller.stack.push(ctx.newString("main")); - ctx.pushFrame(CLASSES.getMethod(CLASSES.java_lang_Thread, "I..(Ljava/lang/String;)V"), 2); - ctx.execute(caller); + + var synthFrame1 = new Frame(CLASSES.getMethod(CLASSES.java_lang_Thread, "I..(Ljava/lang/String;)V"), + [ runtime.mainThread, ctx.newString("main") ], 0); + ctx.frames.push(synthFrame1); + ctx.execute(synthFrame1); var args = ctx.newArray("[Ljava/lang/String;", mainArgs.length); for (var n = 0; n < mainArgs.length; ++n) args[n] = mainArgs[n] ? ctx.newString(mainArgs[n]) : null; - caller.stack.push(args); - ctx.pushFrame(entryPoint, 1); - ctx.start(caller); + + var synthFrame2 = new Frame(entryPoint, [ args ], 0); + ctx.frames.push(synthFrame2); + ctx.start(synthFrame2); } diff --git a/native.js b/native.js index c9840ce1..c98482e8 100644 --- a/native.js +++ b/native.js @@ -501,9 +501,7 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) { // Create a context for the thread and start it. var ctx = new Context(ctx.runtime); ctx.thread = thread; - var caller = new Frame(); - ctx.frames.push(caller); - caller.stack.push(thread); + var syntheticMethod = { syntheticKey: "ThreadStart0Synthetic:" + thread.class.className + "." + run.name + "." + run.signature, classInfo: { @@ -532,8 +530,10 @@ Native["java/lang/Thread.start0.()V"] = function(ctx, stack) { ], exception_table: [], }; - ctx.pushFrame(syntheticMethod, 1); - ctx.start(caller); + + var synthFrame = new Frame(syntheticMethod, [ thread ], 0) + ctx.frames.push(synthFrame); + ctx.start(synthFrame); } Native["java/lang/Thread.internalExit.()V"] = function(ctx, stack) {