зеркало из https://github.com/mozilla/pluotsorbet.git
This commit is contained in:
Родитель
1df7157c8e
Коммит
f81fa7db28
|
@ -8,10 +8,6 @@ function throwHelper(e) {
|
|||
throw e;
|
||||
}
|
||||
|
||||
function throwYield() {
|
||||
throwHelper(VM.Yield);
|
||||
}
|
||||
|
||||
function throwPause() {
|
||||
throwHelper(VM.Pause);
|
||||
}
|
110
context.ts
110
context.ts
|
@ -167,6 +167,16 @@ module J2ME {
|
|||
}
|
||||
|
||||
executeNewFrameSet(frames: Frame []) {
|
||||
var self = this;
|
||||
function flattenFrameSet() {
|
||||
// Append all the current frames to the parent frame set, so a single frame stack
|
||||
// exists when the bailout finishes.
|
||||
var currentFrames = self.frames;
|
||||
self.frames = self.frameSets.pop();
|
||||
for (var i = 0; i < currentFrames.length; i++) {
|
||||
self.frames.push(currentFrames[i]);
|
||||
}
|
||||
}
|
||||
this.frameSets.push(this.frames);
|
||||
this.frames = frames;
|
||||
try {
|
||||
|
@ -176,17 +186,15 @@ module J2ME {
|
|||
traceWriter.enter("> " + MethodType[MethodType.Interpreted][0] + " " + frameDetails);
|
||||
}
|
||||
var returnValue = VM.execute(this);
|
||||
if ($.Y) {
|
||||
flattenFrameSet();
|
||||
return;
|
||||
}
|
||||
if (traceWriter) {
|
||||
traceWriter.leave("<");
|
||||
}
|
||||
} catch (e) {
|
||||
// Append all the current frames to the parent frame set, so a single frame stack
|
||||
// exists when the bailout finishes.
|
||||
var currentFrames = this.frames;
|
||||
this.frames = this.frameSets.pop();
|
||||
for (var i = 0; i < currentFrames.length; i++) {
|
||||
this.frames.push(currentFrames[i]);
|
||||
}
|
||||
flattenFrameSet();
|
||||
if (traceWriter) {
|
||||
traceWriter.leave("< " + e);
|
||||
}
|
||||
|
@ -248,42 +256,17 @@ module J2ME {
|
|||
if (!message)
|
||||
message = "";
|
||||
message = "" + message;
|
||||
var syntheticMethod = new MethodInfo({
|
||||
name: "RaiseExceptionSynthetic",
|
||||
signature: "()V",
|
||||
isStatic: true,
|
||||
classInfo: {
|
||||
className: className,
|
||||
vmc: {},
|
||||
vfc: {},
|
||||
constant_pool: [
|
||||
null,
|
||||
{tag: TAGS.CONSTANT_Class, name_index: 2},
|
||||
{bytes: className},
|
||||
{tag: TAGS.CONSTANT_String, string_index: 4},
|
||||
{bytes: message},
|
||||
{tag: TAGS.CONSTANT_Methodref, class_index: 1, name_and_type_index: 6},
|
||||
{name_index: 7, signature_index: 8},
|
||||
{bytes: "<init>"},
|
||||
{bytes: "(Ljava/lang/String;)V"},
|
||||
],
|
||||
},
|
||||
code: new Uint8Array([
|
||||
0xbb, 0x00, 0x01, // new <idx=1>
|
||||
0x59, // dup
|
||||
0x12, 0x03, // ldc <idx=2>
|
||||
0xb7, 0x00, 0x05, // invokespecial <idx=5>
|
||||
0xbf // athrow
|
||||
])
|
||||
});
|
||||
// pushFrame() is not used since the invoker may be a compiled frame.
|
||||
var callee = new Frame(syntheticMethod, [], 0);
|
||||
this.frames.push(callee);
|
||||
var classInfo = CLASSES.getClass(className);
|
||||
|
||||
var exception = new classInfo.klass();
|
||||
var methodInfo = CLASSES.getMethod(classInfo, "I.<init>.(Ljava/lang/String;)V");
|
||||
jsGlobal[methodInfo.mangledClassAndMethodName](message ? $S(message) : null);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
||||
raiseExceptionAndYield(className, message?) {
|
||||
this.raiseException(className, message);
|
||||
throwYield();
|
||||
}
|
||||
|
||||
setCurrent() {
|
||||
|
@ -301,19 +284,15 @@ module J2ME {
|
|||
Instrument.callResumeHooks(this.current());
|
||||
this.setCurrent();
|
||||
do {
|
||||
try {
|
||||
VM.execute(this);
|
||||
} catch (e) {
|
||||
switch (e) {
|
||||
case VM.Yield:
|
||||
// Ignore the yield and continue executing instructions on this thread.
|
||||
break;
|
||||
case VM.Pause:
|
||||
Instrument.callPauseHooks(this.current());
|
||||
return;
|
||||
default:
|
||||
throwHelper(e);
|
||||
}
|
||||
VM.execute(this);
|
||||
if ($.Y === VmState.Yielding) {
|
||||
// Ignore the yield and continue executing instructions on this thread.
|
||||
$.Y = VmState.Running;
|
||||
continue;
|
||||
} else if ($.Y === VmState.Pausing) {
|
||||
$.Y = VmState.Running;
|
||||
Instrument.callPauseHooks(this.current());
|
||||
return;
|
||||
}
|
||||
} while (this.frames.length !== 0);
|
||||
}
|
||||
|
@ -322,20 +301,13 @@ module J2ME {
|
|||
var ctx = this;
|
||||
this.setCurrent();
|
||||
Instrument.callResumeHooks(ctx.current());
|
||||
try {
|
||||
VM.execute(ctx);
|
||||
} catch (e) {
|
||||
switch (e) {
|
||||
case VM.Yield:
|
||||
break;
|
||||
case VM.Pause:
|
||||
Instrument.callPauseHooks(ctx.current());
|
||||
return;
|
||||
default:
|
||||
console.info(e);
|
||||
throw e;
|
||||
}
|
||||
VM.execute(ctx);
|
||||
if ($.Y === VmState.Pausing) {
|
||||
$.Y = VmState.Running;
|
||||
Instrument.callPauseHooks(this.current());
|
||||
return;
|
||||
}
|
||||
$.Y = VmState.Running;
|
||||
Instrument.callPauseHooks(ctx.current());
|
||||
|
||||
if (ctx.frames.length === 0) {
|
||||
|
@ -355,7 +327,7 @@ module J2ME {
|
|||
obj[queue] = [];
|
||||
obj[queue].push(this);
|
||||
this.lockLevel = lockLevel;
|
||||
throwPause();
|
||||
$.pause();
|
||||
}
|
||||
|
||||
unblock(obj, queue, notifyAll, callback) {
|
||||
|
@ -380,8 +352,12 @@ module J2ME {
|
|||
obj.ready = [];
|
||||
obj.ready.push(this);
|
||||
} else {
|
||||
while (this.lockLevel-- > 0)
|
||||
while (this.lockLevel-- > 0) {
|
||||
this.monitorEnter(obj);
|
||||
if ($.Y === VmState.Pausing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.resume();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ module J2ME {
|
|||
|
||||
function throw_(ex, ctx) {
|
||||
var exClass = ex.class;
|
||||
if (!ex.stackTrace) {
|
||||
ex.stackTrace = [];
|
||||
}
|
||||
|
||||
var stackTrace = ex.stackTrace;
|
||||
|
||||
|
@ -960,6 +963,9 @@ module J2ME {
|
|||
ctx.raiseExceptionAndYield("java/lang/NullPointerException");
|
||||
}
|
||||
ctx.monitorEnter(obj);
|
||||
if ($.Y === VmState.Pausing) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Bytecodes.MONITOREXIT:
|
||||
var obj = stack.pop();
|
||||
|
@ -1045,6 +1051,9 @@ module J2ME {
|
|||
var returnValue;
|
||||
try {
|
||||
returnValue = fn.apply(obj, args);
|
||||
if ($.Y) {
|
||||
return;
|
||||
}
|
||||
} catch (ex) {
|
||||
throw_(ex, ctx);
|
||||
continue;
|
||||
|
|
|
@ -567,7 +567,7 @@ Native.create("java/lang/Thread.sleep.(J)V", function(delay) {
|
|||
}, true);
|
||||
|
||||
Native.create("java/lang/Thread.yield.()V", function() {
|
||||
throwYield();
|
||||
$.yield();
|
||||
});
|
||||
|
||||
Native.create("java/lang/Thread.activeCount.()I", function(ctx) {
|
||||
|
|
|
@ -96,7 +96,7 @@ function executePromise(ret, doReturn, ctx, key) {
|
|||
Instrument.enterAsyncNative(key, ret);
|
||||
}
|
||||
|
||||
throwPause();
|
||||
$.pause();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,9 +135,7 @@ function createAlternateImpl(object, key, fn, usesPromise) {
|
|||
var ret = fn.apply(this, args);
|
||||
return postExec(ret, doReturn, ctx, key);
|
||||
} catch(e) {
|
||||
if (e === VM.Pause || e === VM.Yield) {
|
||||
throwHelper(e);
|
||||
} else if (e.name === "TypeError") {
|
||||
if (e.name === "TypeError") {
|
||||
// JavaScript's TypeError is analogous to a NullPointerException.
|
||||
console.log(e.stack);
|
||||
ctx.raiseExceptionAndYield("java/lang/NullPointerException", e);
|
||||
|
|
24
runtime.ts
24
runtime.ts
|
@ -285,6 +285,12 @@ module J2ME {
|
|||
}
|
||||
}
|
||||
|
||||
export enum VmState {
|
||||
Running = 0,
|
||||
Yielding = 1,
|
||||
Pausing = 2
|
||||
}
|
||||
|
||||
export class Runtime extends RuntimeTemplate {
|
||||
private static _nextId: number = 0;
|
||||
id: number;
|
||||
|
@ -292,7 +298,7 @@ module J2ME {
|
|||
/**
|
||||
* Are we currently unwinding the stack because of a Yield?
|
||||
*/
|
||||
Y: boolean = false;
|
||||
Y: VmState = VmState.Running;
|
||||
|
||||
/**
|
||||
* Bailout callback whenever a JIT frame is unwound.
|
||||
|
@ -301,6 +307,14 @@ module J2ME {
|
|||
|
||||
}
|
||||
|
||||
yield() {
|
||||
this.Y = VmState.Yielding;
|
||||
}
|
||||
|
||||
pause() {
|
||||
this.Y = VmState.Pausing;
|
||||
}
|
||||
|
||||
constructor(jvm: JVM) {
|
||||
super(jvm);
|
||||
this.id = Runtime._nextId ++;
|
||||
|
@ -710,12 +724,10 @@ module J2ME {
|
|||
? methodInfo.classInfo.getClassObject($.ctx)
|
||||
: frame.getLocal(0);
|
||||
}
|
||||
try {
|
||||
$.ctx.monitorEnter(frame.lockObject);
|
||||
} catch (e) {
|
||||
// Ensure the frame gets pushed on vm pause.
|
||||
$.ctx.monitorEnter(frame.lockObject);
|
||||
if ($.Y === VmState.Pausing) {
|
||||
$.ctx.frames.push(frame);
|
||||
throw e;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return $.ctx.executeNewFrameSet([frame]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче