зеркало из https://github.com/mozilla/pluotsorbet.git
Коммит
98a73b5b55
210
jit/baseline.ts
210
jit/baseline.ts
|
@ -312,7 +312,10 @@ module J2ME {
|
|||
*/
|
||||
static stackNames = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "_O", "P", "Q", "R", "S", "T", "_U", "V", "W", "X", "Y", "Z"];
|
||||
|
||||
private hasUnwindThrow;
|
||||
/**
|
||||
* Indicates whether a unwind throw was emitted.
|
||||
*/
|
||||
private hasUnwindThrow: boolean;
|
||||
|
||||
constructor(methodInfo: MethodInfo, target: CompilationTarget) {
|
||||
this.methodInfo = methodInfo;
|
||||
|
@ -329,8 +332,8 @@ module J2ME {
|
|||
this.hasHandlers = !!methodInfo.exception_table.length;
|
||||
this.hasMonitorEnter = false;
|
||||
this.blockStackHeightMap = [0];
|
||||
this.bodyEmitter = new Emitter(target !== CompilationTarget.Runtime);
|
||||
this.blockEmitter = new Emitter(target !== CompilationTarget.Runtime);
|
||||
this.bodyEmitter = new Emitter(!release);
|
||||
this.blockEmitter = new Emitter(!release);
|
||||
this.target = target;
|
||||
this.hasUnwindThrow = false;
|
||||
}
|
||||
|
@ -351,10 +354,10 @@ module J2ME {
|
|||
this.emitBody();
|
||||
|
||||
if (this.variables.length) {
|
||||
this.bodyEmitter.prependLn("var " + this.variables.join(", ") + ";");
|
||||
this.bodyEmitter.prependLn("var " + this.variables.join(",") + ";");
|
||||
}
|
||||
if (this.hasMonitorEnter) {
|
||||
this.bodyEmitter.prependLn("var th = $.ctx.thread;");
|
||||
this.bodyEmitter.prependLn("var th=$.ctx.thread;");
|
||||
}
|
||||
return new CompiledMethodInfo(this.parameters, this.bodyEmitter.toString(), this.referencedClasses, this.blockMap.getOSREntryPoints());
|
||||
}
|
||||
|
@ -409,21 +412,21 @@ module J2ME {
|
|||
needsTry = true;
|
||||
}
|
||||
|
||||
needsWhile && this.bodyEmitter.enter("while (1) {");
|
||||
needsTry && this.bodyEmitter.enter("try {");
|
||||
this.bodyEmitter.writeLn("var label = 0;");
|
||||
needsWhile && this.bodyEmitter.enter("while(1){");
|
||||
needsTry && this.bodyEmitter.enter("try{");
|
||||
this.bodyEmitter.writeLn("var label=0;");
|
||||
this.bodyEmitter.writeLns(Relooper.render(this.entryBlock));
|
||||
|
||||
emitCompilerAssertions && this.bodyEmitter.writeLn("J2ME.Debug.assert(false, 'Invalid PC: ' + pc)");
|
||||
|
||||
if (needsTry) {
|
||||
this.bodyEmitter.leaveAndEnter("} catch (ex) {");
|
||||
this.bodyEmitter.leaveAndEnter("}catch(ex){");
|
||||
if (this.hasUnwindThrow) {
|
||||
var local = this.local.join(", ");
|
||||
var stack = this.stack.join(", ");
|
||||
this.bodyEmitter.writeLn("if (U) { $.T(ex, [" + local + "], [" + stack + "], " + this.lockObject + "); return; }");
|
||||
var local = this.local.join(",");
|
||||
var stack = this.stack.join(",");
|
||||
this.bodyEmitter.writeLn("if(U){$.T(ex,[" + local + "],[" + stack + "]," + this.lockObject + ");return;}");
|
||||
}
|
||||
this.bodyEmitter.writeLn(this.getStackName(0) + " = TE(ex);");
|
||||
this.bodyEmitter.writeLn(this.getStackName(0) + "=TE(ex);");
|
||||
this.blockStack = [this.getStackName(0)];
|
||||
this.sp = 1;
|
||||
if (this.hasHandlers) {
|
||||
|
@ -451,12 +454,10 @@ module J2ME {
|
|||
if (classInfo.isInterface) {
|
||||
check = "IOI";
|
||||
}
|
||||
check += "(" + this.peek(Kind.Reference) + ", " + classConstant(classInfo) + ")";
|
||||
check = " && " + check;
|
||||
check += "(" + this.peek(Kind.Reference) + "," + classConstant(classInfo) + ")";
|
||||
check = "&&" + check;
|
||||
}
|
||||
this.bodyEmitter.enter("if (pc >= " + handler.start_pc + " && pc < " + handler.end_pc + check + ") {");
|
||||
this.bodyEmitter.writeLn("pc = " + this.getBlockIndex(handler.handler_pc) + "; continue;");
|
||||
this.bodyEmitter.leave("}");
|
||||
this.bodyEmitter.writeLn("if(pc>=" + handler.start_pc + "&&pc<" + handler.end_pc + check + "){pc=" + this.getBlockIndex(handler.handler_pc) + ";continue;}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -520,19 +521,19 @@ module J2ME {
|
|||
local.push(this.getLocalName(i));
|
||||
}
|
||||
if (local.length) {
|
||||
this.bodyEmitter.writeLn("var " + local.join(", ") + ";");
|
||||
this.bodyEmitter.writeLn("var " + local.join(",") + ";");
|
||||
}
|
||||
if (!this.methodInfo.isStatic) {
|
||||
this.bodyEmitter.writeLn(this.getLocal(0) + " = this;");
|
||||
this.bodyEmitter.writeLn(this.getLocal(0) + "=this;");
|
||||
}
|
||||
var stack = this.stack;
|
||||
for (var i = 0; i < this.methodInfo.max_stack; i++) {
|
||||
stack.push(this.getStackName(i));
|
||||
}
|
||||
if (stack.length) {
|
||||
this.bodyEmitter.writeLn("var " + stack.join(", ") + ";");
|
||||
this.bodyEmitter.writeLn("var " + stack.join(",") + ";");
|
||||
}
|
||||
this.bodyEmitter.writeLn("var pc = 0;");
|
||||
this.bodyEmitter.writeLn("var pc=0;");
|
||||
if (this.hasHandlers) {
|
||||
this.bodyEmitter.writeLn("var ex;");
|
||||
}
|
||||
|
@ -566,18 +567,20 @@ module J2ME {
|
|||
|
||||
if (needsOSREntryPoint) {
|
||||
// Are we doing an OSR?
|
||||
this.bodyEmitter.enter("if (O) {");
|
||||
this.bodyEmitter.writeLn("var local = O.local;");
|
||||
this.bodyEmitter.enter("if(O){");
|
||||
this.bodyEmitter.writeLn("var _=O.local;");
|
||||
|
||||
// Restore locals.
|
||||
var restoreLocals = [];
|
||||
for (var i = 0; i < this.methodInfo.max_locals; i++) {
|
||||
this.bodyEmitter.writeLn(this.getLocal(i) + " = local[" + i + "];");
|
||||
restoreLocals.push(this.getLocal(i) + "=_[" + i + "]");
|
||||
}
|
||||
this.bodyEmitter.writeLn(restoreLocals.join(",") + ";");
|
||||
this.needsVariable("re");
|
||||
this.bodyEmitter.writeLn("pc = O.pc;");
|
||||
this.bodyEmitter.writeLn("O = null;");
|
||||
this.bodyEmitter.writeLn("pc=O.pc;");
|
||||
this.bodyEmitter.writeLn("O=null;");
|
||||
if (this.methodInfo.isSynchronized) {
|
||||
this.bodyEmitter.leaveAndEnter("} else {");
|
||||
this.bodyEmitter.leaveAndEnter("}else{");
|
||||
this.emitMonitorEnter(this.bodyEmitter, 0, this.lockObject);
|
||||
}
|
||||
this.bodyEmitter.leave("}");
|
||||
|
@ -605,7 +608,7 @@ module J2ME {
|
|||
if (i === 0 || // First block always gets a entry point.
|
||||
(block.isLoopHeader && !block.isInnerLoopHeader()) || // Outer loop headers need entry points so we can OSR.
|
||||
block.isExceptionEntry) {
|
||||
Relooper.addBranch(entryBlock, block.relooperBlockID, "pc === " + block.startBci);
|
||||
Relooper.addBranch(entryBlock, block.relooperBlockID, "pc===" + block.startBci);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,7 +672,7 @@ module J2ME {
|
|||
}
|
||||
|
||||
emitStoreLocal(kind: Kind, i: number) {
|
||||
this.blockEmitter.writeLn(this.getLocal(i) + " = " + this.pop(kind, Precedence.Sequence) + ";");
|
||||
this.blockEmitter.writeLn(this.getLocal(i) + "=" + this.pop(kind, Precedence.Sequence) + ";");
|
||||
}
|
||||
|
||||
peekAny(): string {
|
||||
|
@ -686,7 +689,7 @@ module J2ME {
|
|||
|
||||
emitPopTemporaries(n: number) {
|
||||
for (var i = 0; i < n; i++) {
|
||||
this.blockEmitter.writeLn("var t" + i + " = " + this.pop(Kind.Void) + ";");
|
||||
this.blockEmitter.writeLn("var t" + i + "=" + this.pop(Kind.Void) + ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -721,7 +724,7 @@ module J2ME {
|
|||
for (var i = 0; i < this.sp; i++) {
|
||||
var name = this.getStackName(i);
|
||||
if (name !== this.blockStack[i]) {
|
||||
this.blockEmitter.writeLn(name + " = " + this.blockStack[i] + ";");
|
||||
this.blockEmitter.writeLn(name + "=" + this.blockStack[i] + ";");
|
||||
this.blockStack[i] = name;
|
||||
this.blockStackPrecedence[i] = Precedence.Primary;
|
||||
}
|
||||
|
@ -755,7 +758,7 @@ module J2ME {
|
|||
var signature = TypeDescriptor.makeTypeDescriptor(fieldInfo.signature);
|
||||
var value = this.pop(signature.kind, Precedence.Sequence);
|
||||
var object = isStatic ? this.runtimeClass(fieldInfo.classInfo) : this.pop(Kind.Reference);
|
||||
this.blockEmitter.writeLn(object + "." + fieldInfo.mangledName + " = " + value + ";");
|
||||
this.blockEmitter.writeLn(object + "." + fieldInfo.mangledName + "=" + value + ";");
|
||||
}
|
||||
|
||||
setBlockStackHeight(pc: number, height: number) {
|
||||
|
@ -777,18 +780,18 @@ module J2ME {
|
|||
|
||||
emitIfNull(block: Block, stream: BytecodeStream, condition: Condition) {
|
||||
var x = this.pop(Kind.Reference);
|
||||
this.emitIf(block, stream, x + " " + conditionToOperator(condition) + " null");
|
||||
this.emitIf(block, stream, x + conditionToOperator(condition) + "null");
|
||||
}
|
||||
|
||||
emitIfSame(block: Block, stream: BytecodeStream, kind: Kind, condition: Condition) {
|
||||
var y = this.pop(kind);
|
||||
var x = this.pop(kind);
|
||||
this.emitIf(block, stream, x + " " + conditionToOperator(condition) + " " + y);
|
||||
this.emitIf(block, stream, x + conditionToOperator(condition) + y);
|
||||
}
|
||||
|
||||
emitIfZero(block: Block, stream: BytecodeStream, condition: Condition) {
|
||||
var x = this.pop(Kind.Int, Precedence.Relational);
|
||||
this.emitIf(block, stream, x + " " + conditionToOperator(condition) + " 0");
|
||||
this.emitIf(block, stream, x + conditionToOperator(condition) + "0");
|
||||
}
|
||||
|
||||
runtimeClass(classInfo: ClassInfo) {
|
||||
|
@ -851,12 +854,12 @@ module J2ME {
|
|||
object = this.pop(Kind.Reference);
|
||||
if (opcode === Bytecodes.INVOKESPECIAL) {
|
||||
args.unshift(object);
|
||||
call = methodInfo.mangledClassAndMethodName + ".call(" + args.join(", ") + ")";
|
||||
call = methodInfo.mangledClassAndMethodName + ".call(" + args.join(",") + ")";
|
||||
} else {
|
||||
call = object + "." + methodInfo.mangledName + "(" + args.join(", ") + ")";
|
||||
call = object + "." + methodInfo.mangledName + "(" + args.join(",") + ")";
|
||||
}
|
||||
} else {
|
||||
call = methodInfo.mangledClassAndMethodName + "(" + args.join(", ") + ")";
|
||||
call = methodInfo.mangledClassAndMethodName + "(" + args.join(",") + ")";
|
||||
}
|
||||
if (methodInfo.implKey in inlineMethods) {
|
||||
emitDebugInfoComments && this.blockEmitter.writeLn("// Inlining: " + methodInfo.implKey);
|
||||
|
@ -864,7 +867,7 @@ module J2ME {
|
|||
}
|
||||
this.needsVariable("re");
|
||||
this.flushBlockStack();
|
||||
this.blockEmitter.writeLn("re = " + call + ";");
|
||||
this.blockEmitter.writeLn("re=" + call + ";");
|
||||
if (calleeCanYield) {
|
||||
this.emitUnwind(this.blockEmitter, String(this.pc), String(nextPC));
|
||||
} else {
|
||||
|
@ -880,9 +883,9 @@ module J2ME {
|
|||
var value = this.pop(stackKind(kind), Precedence.Sequence);
|
||||
var index = this.pop(Kind.Int, Precedence.Sequence);
|
||||
var array = this.pop(Kind.Reference, Precedence.Sequence);
|
||||
emitCheckArrayBounds && this.blockEmitter.writeLn("CAB(" + array + ", " + index + ");");
|
||||
emitCheckArrayBounds && this.blockEmitter.writeLn("CAB(" + array + "," + index + ");");
|
||||
if (kind === Kind.Reference) {
|
||||
emitCheckArrayStore && this.blockEmitter.writeLn("CAS(" + array + ", " + value + ");");
|
||||
emitCheckArrayStore && this.blockEmitter.writeLn("CAS(" + array + "," + value + ");");
|
||||
}
|
||||
this.blockEmitter.writeLn(array + "[" + index + "] = " + value + ";");
|
||||
}
|
||||
|
@ -890,12 +893,12 @@ module J2ME {
|
|||
emitLoadIndexed(kind: Kind) {
|
||||
var index = this.pop(Kind.Int, Precedence.Sequence);
|
||||
var array = this.pop(Kind.Reference, Precedence.Sequence);
|
||||
emitCheckArrayBounds && this.blockEmitter.writeLn("CAB(" + array + ", " + index + ");");
|
||||
emitCheckArrayBounds && this.blockEmitter.writeLn("CAB(" + array + "," + index + ");");
|
||||
this.emitPush(kind, array + "[" + index + "]", Precedence.Member);
|
||||
}
|
||||
|
||||
emitIncrement(stream: BytecodeStream) {
|
||||
this.blockEmitter.writeLn(this.getLocal(stream.readLocalIndex()) + " += " + stream.readIncrement() + ";");
|
||||
this.blockEmitter.writeLn(this.getLocal(stream.readLocalIndex()) + "+=" + stream.readIncrement() + ";");
|
||||
}
|
||||
|
||||
emitGoto(block: Block, stream: BytecodeStream) {
|
||||
|
@ -918,7 +921,7 @@ module J2ME {
|
|||
this.emitPush(Kind.Double, doubleConstant(entry.double), Precedence.Primary);
|
||||
return;
|
||||
case TAGS.CONSTANT_Long:
|
||||
this.emitPush(Kind.Long, "Long.fromBits(" + entry.lowBits + ", " + entry.highBits + ")", Precedence.Primary);
|
||||
this.emitPush(Kind.Long, "Long.fromBits(" + entry.lowBits + "," + entry.highBits + ")", Precedence.Primary);
|
||||
return;
|
||||
case TAGS.CONSTANT_String:
|
||||
entry = cp[entry.string_index];
|
||||
|
@ -953,7 +956,7 @@ module J2ME {
|
|||
if (classInfo.isInterface) {
|
||||
call = "CCI";
|
||||
}
|
||||
this.blockEmitter.writeLn(call + "(" + object + ", " + classConstant(classInfo) + ");");
|
||||
this.blockEmitter.writeLn(call + "(" + object + "," + classConstant(classInfo) + ");");
|
||||
}
|
||||
|
||||
emitInstanceOf(cpi: number) {
|
||||
|
@ -963,7 +966,7 @@ module J2ME {
|
|||
if (classInfo.isInterface) {
|
||||
call = "IOI";
|
||||
}
|
||||
this.emitPush(Kind.Int, call + "(" + object + ", " + classConstant(classInfo) + ") | 0", Precedence.BitwiseOR);
|
||||
this.emitPush(Kind.Int, call + "(" + object + "," + classConstant(classInfo) + ")|0", Precedence.BitwiseOR);
|
||||
}
|
||||
|
||||
emitArrayLength() {
|
||||
|
@ -974,7 +977,7 @@ module J2ME {
|
|||
var classInfo = this.lookupClass(cpi);
|
||||
this.emitClassInitializationCheck(classInfo);
|
||||
var length = this.pop(Kind.Int);
|
||||
this.emitPush(Kind.Reference, "NA(" + classConstant(classInfo) + ", " + length + ")", Precedence.Call);
|
||||
this.emitPush(Kind.Reference, "NA(" + classConstant(classInfo) + "," + length + ")", Precedence.Call);
|
||||
}
|
||||
|
||||
emitNewMultiObjectArray(cpi: number, stream: BytecodeStream) {
|
||||
|
@ -984,25 +987,30 @@ module J2ME {
|
|||
for (var i = numDimensions - 1; i >= 0; i--) {
|
||||
dimensions[i] = this.pop(Kind.Int);
|
||||
}
|
||||
this.emitPush(Kind.Reference, "NM(" + classConstant(classInfo) + ", [" + dimensions.join(", ") + "])", Precedence.Call);
|
||||
this.emitPush(Kind.Reference, "NM(" + classConstant(classInfo) + ",[" + dimensions.join(",") + "])", Precedence.Call);
|
||||
}
|
||||
|
||||
private emitUnwind(emitter: Emitter, pc: string, nextPC: string, forceInline: boolean = false) {
|
||||
// Only emit throw unwinds if it saves on code size.
|
||||
if (!forceInline && this.blockMap.invokeCount > 2 && this.stack.length < 256) {
|
||||
// Only emit unwind throws if it saves on code size.
|
||||
if (!forceInline && this.blockMap.invokeCount > 2 &&
|
||||
this.stack.length < 8) {
|
||||
this.flushBlockStack();
|
||||
emitter.writeLn("U && TU(" + UnwindThrowLocation.encode(pc, nextPC, this.sp) + ");");
|
||||
if (<any>nextPC - <any>pc === 3) {
|
||||
emitter.writeLn("U&&B" + this.sp + "(" + pc + ");");
|
||||
} else {
|
||||
emitter.writeLn("U&&B" + this.sp + "(" + pc + "," + nextPC + ");");
|
||||
}
|
||||
this.hasUnwindThrow = true;
|
||||
} else {
|
||||
var local = this.local.join(", ");
|
||||
var stack = this.blockStack.slice(0, this.sp).join(", ");
|
||||
emitter.writeLn("if (U) { $.B(" + pc + ", " + nextPC + ", [" + local + "], [" + stack + "], " + this.lockObject + "); return; }");
|
||||
var local = this.local.join(",");
|
||||
var stack = this.blockStack.slice(0, this.sp).join(",");
|
||||
emitter.writeLn("if(U){$.B(" + pc + "," + nextPC + ",[" + local + "],[" + stack + "]," + this.lockObject + ");return;}");
|
||||
}
|
||||
baselineCounter && baselineCounter.count("emitUnwind");
|
||||
}
|
||||
|
||||
emitNoUnwindAssertion() {
|
||||
this.blockEmitter.writeLn("if (U) { J2ME.Debug.assert(false, 'Unexpected unwind.'); }");
|
||||
this.blockEmitter.writeLn("if(U){J2ME.Debug.assert(false,'Unexpected unwind.');}");
|
||||
}
|
||||
|
||||
emitUndefinedReturnAssertion() {
|
||||
|
@ -1013,8 +1021,8 @@ module J2ME {
|
|||
this.hasMonitorEnter = true;
|
||||
|
||||
this.needsVariable("lk");
|
||||
emitter.writeLn("lk = " + object + "._lock;");
|
||||
emitter.enter("if (lk && lk.level === 0) { lk.thread = th; lk.level = 1; } else { ME(" + object + ");");
|
||||
emitter.writeLn("lk=" + object + "._lock;");
|
||||
emitter.enter("if(lk&&lk.level===0){lk.thread=th;lk.level=1;}else{ME(" + object + ");");
|
||||
this.emitUnwind(emitter, String(this.pc), String(nextPC), true);
|
||||
emitter.leave("}");
|
||||
}
|
||||
|
@ -1023,13 +1031,13 @@ module J2ME {
|
|||
if (!emitCheckPreemption) {
|
||||
return;
|
||||
}
|
||||
emitter.writeLn("PS ++;");
|
||||
emitter.writeLn("if ((PS & " + preemptionSampleMask + ") === 0) PE();");
|
||||
emitter.writeLn("PS++;");
|
||||
emitter.writeLn("if((PS&" + preemptionSampleMask + ")===0)PE();");
|
||||
this.emitUnwind(emitter, String(nextPC), String(nextPC));
|
||||
}
|
||||
|
||||
private emitMonitorExit(emitter: Emitter, object: string) {
|
||||
emitter.writeLn("if (" + object + "._lock.level === 1 && " + object + "._lock.ready.length === 0) " + object + "._lock.level = 0; else MX(" + object + ");");
|
||||
emitter.writeLn("if(" + object + "._lock.level===1&&" + object + "._lock.ready.length===0)" + object + "._lock.level=0;else MX(" + object + ");");
|
||||
}
|
||||
|
||||
emitStackOp(opcode: Bytecodes) {
|
||||
|
@ -1091,17 +1099,17 @@ module J2ME {
|
|||
}
|
||||
var v;
|
||||
switch(opcode) {
|
||||
case Bytecodes.IADD: v = x + " + " + y + " | 0"; break;
|
||||
case Bytecodes.ISUB: v = x + " - " + y + " | 0"; break;
|
||||
case Bytecodes.IMUL: v = "Math.imul(" + x + ", " + y + ")"; break;
|
||||
case Bytecodes.IDIV: v = x + " / " + y + " | 0"; break;
|
||||
case Bytecodes.IREM: v = x + " % " + y; break;
|
||||
case Bytecodes.IADD: v = x + "+" + y + "|0"; break;
|
||||
case Bytecodes.ISUB: v = x + "-" + y + "|0"; break;
|
||||
case Bytecodes.IMUL: v = "Math.imul(" + x + "," + y + ")"; break;
|
||||
case Bytecodes.IDIV: v = x + "/" + y + "|0"; break;
|
||||
case Bytecodes.IREM: v = x + "%" + y; break;
|
||||
|
||||
case Bytecodes.FADD: v = "Math.fround(" + x + " + " + y + ")"; break;
|
||||
case Bytecodes.FSUB: v = "Math.fround(" + x + " - " + y + ")"; break;
|
||||
case Bytecodes.FMUL: v = "Math.fround(" + x + " * " + y + ")"; break;
|
||||
case Bytecodes.FDIV: v = "Math.fround(" + x + " / " + y + ")"; break;
|
||||
case Bytecodes.FREM: v = "Math.fround(" + x + " % " + y + ")"; break;
|
||||
case Bytecodes.FADD: v = "Math.fround(" + x + "+" + y + ")"; break;
|
||||
case Bytecodes.FSUB: v = "Math.fround(" + x + "-" + y + ")"; break;
|
||||
case Bytecodes.FMUL: v = "Math.fround(" + x + "*" + y + ")"; break;
|
||||
case Bytecodes.FDIV: v = "Math.fround(" + x + "/" + y + ")"; break;
|
||||
case Bytecodes.FREM: v = "Math.fround(" + x + "%" + y + ")"; break;
|
||||
|
||||
case Bytecodes.LADD: v = x + ".add(" + y + ")"; break;
|
||||
case Bytecodes.LSUB: v = y + ".negate().add(" + x + ")"; break;
|
||||
|
@ -1109,11 +1117,11 @@ module J2ME {
|
|||
case Bytecodes.LDIV: v = x + ".div(" + y + ")"; break;
|
||||
case Bytecodes.LREM: v = x + ".modulo(" + y + ")"; break;
|
||||
|
||||
case Bytecodes.DADD: v = x + " + " + y; break;
|
||||
case Bytecodes.DSUB: v = x + " - " + y; break;
|
||||
case Bytecodes.DMUL: v = x + " * " + y; break;
|
||||
case Bytecodes.DDIV: v = x + " / " + y; break;
|
||||
case Bytecodes.DREM: v = x + " % " + y; break;
|
||||
case Bytecodes.DADD: v = x + "+" + y; break;
|
||||
case Bytecodes.DSUB: v = x + "-" + y; break;
|
||||
case Bytecodes.DMUL: v = x + "*" + y; break;
|
||||
case Bytecodes.DDIV: v = x + "/" + y; break;
|
||||
case Bytecodes.DREM: v = x + "%" + y; break;
|
||||
default:
|
||||
release || assert(false, Bytecodes[opcode]);
|
||||
}
|
||||
|
@ -1124,7 +1132,7 @@ module J2ME {
|
|||
var x = this.pop(kind);
|
||||
switch(kind) {
|
||||
case Kind.Int:
|
||||
this.emitPush(kind, "(- " + x + ") | 0", Precedence.BitwiseOR);
|
||||
this.emitPush(kind, "(- " + x + ")|0", Precedence.BitwiseOR);
|
||||
break;
|
||||
case Kind.Long:
|
||||
this.emitPush(kind, x + ".negate()", Precedence.Member); // TODO: Or is it call?
|
||||
|
@ -1143,9 +1151,9 @@ module J2ME {
|
|||
var x = this.pop(kind);
|
||||
var v;
|
||||
switch(opcode) {
|
||||
case Bytecodes.ISHL: this.emitPush(kind, x + " << " + s, Precedence.BitwiseShift); return;
|
||||
case Bytecodes.ISHR: this.emitPush(kind, x + " >> " + s, Precedence.BitwiseShift); return;
|
||||
case Bytecodes.IUSHR: this.emitPush(kind, x + " >>> " + s, Precedence.BitwiseShift); return;
|
||||
case Bytecodes.ISHL: this.emitPush(kind, x + "<<" + s, Precedence.BitwiseShift); return;
|
||||
case Bytecodes.ISHR: this.emitPush(kind, x + ">>" + s, Precedence.BitwiseShift); return;
|
||||
case Bytecodes.IUSHR: this.emitPush(kind, x + ">>>" + s, Precedence.BitwiseShift); return;
|
||||
|
||||
case Bytecodes.LSHL: v = x + ".shiftLeft(" + s + ")"; break;
|
||||
case Bytecodes.LSHR: v = x + ".shiftRight(" + s + ")"; break;
|
||||
|
@ -1161,9 +1169,9 @@ module J2ME {
|
|||
var x = this.pop(kind);
|
||||
var v;
|
||||
switch(opcode) {
|
||||
case Bytecodes.IAND: this.emitPush(kind, x + " & " + y, Precedence.BitwiseAND); return;
|
||||
case Bytecodes.IOR: this.emitPush(kind, x + " | " + y, Precedence.BitwiseOR); return;
|
||||
case Bytecodes.IXOR: this.emitPush(kind, x + " ^ " + y, Precedence.BitwiseXOR); return;
|
||||
case Bytecodes.IAND: this.emitPush(kind, x + "&" + y, Precedence.BitwiseAND); return;
|
||||
case Bytecodes.IOR: this.emitPush(kind, x + "|" + y, Precedence.BitwiseOR); return;
|
||||
case Bytecodes.IXOR: this.emitPush(kind, x + "^" + y, Precedence.BitwiseXOR); return;
|
||||
|
||||
case Bytecodes.LAND: v = x + ".and(" + y + ")"; break;
|
||||
case Bytecodes.LOR: v = x + ".or(" + y + ")"; break;
|
||||
|
@ -1181,9 +1189,9 @@ module J2ME {
|
|||
case Bytecodes.I2L: v = "Long.fromInt(" + x + ")"; break;
|
||||
case Bytecodes.I2F:
|
||||
case Bytecodes.I2D: v = x; break;
|
||||
case Bytecodes.I2B: v = "(" + x + " << 24) >> 24"; break;
|
||||
case Bytecodes.I2C: v = x + " & 0xffff"; break;
|
||||
case Bytecodes.I2S: v = "(" + x + " << 16) >> 16"; break;
|
||||
case Bytecodes.I2B: v = "(" + x + "<<24)>>24"; break;
|
||||
case Bytecodes.I2C: v = x + "&0xffff"; break;
|
||||
case Bytecodes.I2S: v = "(" + x + "<<16)>>16"; break;
|
||||
case Bytecodes.L2I: v = x + ".toInt()"; break;
|
||||
case Bytecodes.L2F: v = "Math.fround(" + x + ".toNumber())"; break;
|
||||
case Bytecodes.L2D: v = x + ".toNumber()"; break;
|
||||
|
@ -1205,22 +1213,22 @@ module J2ME {
|
|||
// Get the top stack slot and make sure it is also it in the |blockStack|.
|
||||
var s = this.blockStack[sp] = this.getStackName(sp);
|
||||
if (kind === Kind.Long) {
|
||||
this.blockEmitter.enter("if (" + x + ".greaterThan(" + y + ")) {");
|
||||
this.blockEmitter.writeLn(s + " = 1");
|
||||
this.blockEmitter.leaveAndEnter("} else if (" + x + ".lessThan(" + y + ")) {");
|
||||
this.blockEmitter.writeLn(s + " = -1");
|
||||
this.blockEmitter.leaveAndEnter("} else {");
|
||||
this.blockEmitter.writeLn(s + " = 0");
|
||||
this.blockEmitter.enter("if(" + x + ".greaterThan(" + y + ")){");
|
||||
this.blockEmitter.writeLn(s + "=1");
|
||||
this.blockEmitter.leaveAndEnter("}else if(" + x + ".lessThan(" + y + ")){");
|
||||
this.blockEmitter.writeLn(s + "=-1");
|
||||
this.blockEmitter.leaveAndEnter("}else{");
|
||||
this.blockEmitter.writeLn(s + "=0");
|
||||
this.blockEmitter.leave("}");
|
||||
} else {
|
||||
this.blockEmitter.enter("if (isNaN(" + x + ") || isNaN(" + y + ")) {");
|
||||
this.blockEmitter.writeLn(s + " = " + (isLessThan ? "-1" : "1"));
|
||||
this.blockEmitter.leaveAndEnter("} else if (" + x + " > " + y + ") {");
|
||||
this.blockEmitter.writeLn(s + " = 1");
|
||||
this.blockEmitter.leaveAndEnter("} else if (" + x + " < " + y + ") {");
|
||||
this.blockEmitter.writeLn(s + " = -1");
|
||||
this.blockEmitter.leaveAndEnter("} else {");
|
||||
this.blockEmitter.writeLn(s + " = 0");
|
||||
this.blockEmitter.enter("if(isNaN(" + x + ")||isNaN(" + y + ")){");
|
||||
this.blockEmitter.writeLn(s + "=" + (isLessThan ? "-1" : "1"));
|
||||
this.blockEmitter.leaveAndEnter("}else if(" + x + ">" + y + ") {");
|
||||
this.blockEmitter.writeLn(s + "=1");
|
||||
this.blockEmitter.leaveAndEnter("}else if(" + x + "<" + y + "){");
|
||||
this.blockEmitter.writeLn(s + "=-1");
|
||||
this.blockEmitter.leaveAndEnter("}else{");
|
||||
this.blockEmitter.writeLn(s + "=0");
|
||||
this.blockEmitter.leave("}");
|
||||
}
|
||||
}
|
||||
|
@ -1283,7 +1291,7 @@ module J2ME {
|
|||
|
||||
var flushBlockStackAfter = false;
|
||||
if ((block.isExceptionEntry || block.hasHandlers) && Bytecode.canTrap(opcode)) {
|
||||
this.blockEmitter.writeLn("pc = " + this.pc + ";");
|
||||
this.blockEmitter.writeLn("pc=" + this.pc + ";");
|
||||
flushBlockStackAfter = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ static void PrintDebug(const char *Format, ...);
|
|||
#define DebugDump(x, ...)
|
||||
#endif
|
||||
|
||||
#define INDENTATION 1
|
||||
#define INDENTATION 0
|
||||
|
||||
struct Indenter {
|
||||
static int CurrIndent;
|
||||
|
|
1
jsc.ts
1
jsc.ts
|
@ -187,7 +187,6 @@ module J2ME {
|
|||
|
||||
var jarFiles = Object.create(null);
|
||||
|
||||
release = releaseOption.value;
|
||||
var jvm = new JVM();
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var file = files[i];
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -64,7 +64,7 @@ module J2ME {
|
|||
/**
|
||||
* Enables more compact mangled names. This helps reduce code size but may cause naming collisions.
|
||||
*/
|
||||
var hashedMangledNames = false;
|
||||
var hashedMangledNames = release;
|
||||
|
||||
/**
|
||||
* Traces method execution.
|
||||
|
@ -1909,36 +1909,72 @@ module J2ME {
|
|||
|
||||
export class UnwindThrowLocation {
|
||||
static instance: UnwindThrowLocation = new UnwindThrowLocation();
|
||||
pc: number;
|
||||
sp: number;
|
||||
nextPC: number;
|
||||
constructor() {
|
||||
this.location = 0;
|
||||
this.pc = 0;
|
||||
this.sp = 0;
|
||||
this.nextPC = 0;
|
||||
}
|
||||
static encode(pc, nextPC, sp) {
|
||||
var delta = nextPC - pc;
|
||||
release || assert (delta >= 0 && delta < 8, delta);
|
||||
release || assert (sp >= 0 && sp < 256, sp);
|
||||
return pc << 11 | delta << 8 | sp;
|
||||
}
|
||||
location: number;
|
||||
set(location: number) {
|
||||
this.location = location;
|
||||
setLocation(pc: number, nextPC: number, sp: number) {
|
||||
this.pc = pc;
|
||||
this.sp = sp;
|
||||
this.nextPC = nextPC;
|
||||
return this;
|
||||
}
|
||||
getPC() {
|
||||
return (this.location >> 11) & 0xffff;
|
||||
}
|
||||
getNextPC() {
|
||||
return this.getPC() + ((this.location >> 8) & 0x07);
|
||||
return this.pc;
|
||||
}
|
||||
getSP() {
|
||||
return this.location & 0xff;
|
||||
return this.sp;
|
||||
}
|
||||
getNextPC() {
|
||||
return this.nextPC;
|
||||
}
|
||||
}
|
||||
|
||||
export function throwUnwind(location: number) {
|
||||
if (location === 0) {
|
||||
debugger;
|
||||
}
|
||||
throw UnwindThrowLocation.instance.set(location);
|
||||
/**
|
||||
* Generic unwind throw.
|
||||
*/
|
||||
export function throwUnwind(pc: number, nextPC: number = pc + 3, sp: number = 0) {
|
||||
throw UnwindThrowLocation.instance.setLocation(pc, nextPC, sp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwind throws with different stack heights. This is useful so we can
|
||||
* save a few bytes encoding the stack height in the function name.
|
||||
*/
|
||||
export function throwUnwind0(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 0);
|
||||
}
|
||||
|
||||
export function throwUnwind1(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 1);
|
||||
}
|
||||
|
||||
export function throwUnwind2(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 2);
|
||||
}
|
||||
|
||||
export function throwUnwind3(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 3);
|
||||
}
|
||||
|
||||
export function throwUnwind4(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 4);
|
||||
}
|
||||
|
||||
export function throwUnwind5(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 5);
|
||||
}
|
||||
|
||||
export function throwUnwind6(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 6);
|
||||
}
|
||||
|
||||
export function throwUnwind7(pc: number, nextPC: number = pc + 3) {
|
||||
throwUnwind(pc, nextPC, 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1953,7 +1989,16 @@ var AOTMD = J2ME.aotMetaData;
|
|||
*/
|
||||
var U: J2ME.VMState = J2ME.VMState.Running;
|
||||
|
||||
var TU = J2ME.throwUnwind;
|
||||
// Several unwind throws for different stack heights.
|
||||
|
||||
var B0 = J2ME.throwUnwind0;
|
||||
var B1 = J2ME.throwUnwind1;
|
||||
var B2 = J2ME.throwUnwind2;
|
||||
var B3 = J2ME.throwUnwind3;
|
||||
var B4 = J2ME.throwUnwind4;
|
||||
var B5 = J2ME.throwUnwind5;
|
||||
var B6 = J2ME.throwUnwind6;
|
||||
var B7 = J2ME.throwUnwind7;
|
||||
|
||||
/**
|
||||
* OSR Frame.
|
||||
|
|
Загрузка…
Ссылка в новой задаче