2014-07-06 12:29:36 +04:00
|
|
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Array.prototype.push2 = function (value) {
|
|
|
|
this.push(value);
|
|
|
|
this.push(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
Array.prototype.pop2 = function () {
|
|
|
|
this.pop();
|
|
|
|
return this.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
Array.prototype.top = function () {
|
|
|
|
return this[this.length - 1];
|
|
|
|
}
|
|
|
|
|
2014-07-13 09:19:03 +04:00
|
|
|
var Frame = function(methodInfo) {
|
2014-07-13 11:00:11 +04:00
|
|
|
if (methodInfo) {
|
|
|
|
this.methodInfo = methodInfo;
|
2014-07-13 20:28:19 +04:00
|
|
|
this.cp = methodInfo.classInfo.constant_pool;
|
2014-07-13 11:00:11 +04:00
|
|
|
this.code = methodInfo.code;
|
|
|
|
this.ip = 0;
|
|
|
|
}
|
2014-07-13 10:13:53 +04:00
|
|
|
this.stack = [];
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.getLocal = function(idx) {
|
|
|
|
return this.locals[this.localsBase + idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
Frame.prototype.setLocal = function(idx, value) {
|
|
|
|
this.locals[this.localsBase + idx] = value;
|
|
|
|
}
|
|
|
|
|
2014-07-12 22:54:04 +04:00
|
|
|
Frame.prototype.isWide = function() {
|
2014-07-14 05:36:06 +04:00
|
|
|
return this.code[this.ip - 2] === OPCODES.wide;
|
2014-07-12 22:54:04 +04:00
|
|
|
}
|
|
|
|
|
2014-07-14 05:40:05 +04:00
|
|
|
Frame.prototype.getOp = function() {
|
|
|
|
return this.code[this.ip - 1];
|
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.u16_to_s16 = function(x) {
|
2014-07-06 13:03:36 +04:00
|
|
|
return (x > 0x7fff) ? (x - 0x10000) : x;
|
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.u32_to_s32 = function(x) {
|
2014-07-06 13:03:36 +04:00
|
|
|
return (x > 0x7fffffff) ? (x - 0x100000000) : x;
|
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.read8 = function() {
|
|
|
|
return this.code[this.ip++];
|
2014-07-06 12:29:36 +04:00
|
|
|
};
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.read16 = function() {
|
|
|
|
return this.read8()<<8 | this.read8();
|
2014-07-06 12:29:36 +04:00
|
|
|
};
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.read32 = function() {
|
|
|
|
return this.read16()<<16 | this.read16();
|
2014-07-06 12:29:36 +04:00
|
|
|
};
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.read16signed = function() {
|
|
|
|
return this.u16_to_s16(this.read16());
|
2014-07-06 13:03:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.read32signed = function() {
|
|
|
|
return this.u32_to_s32(this.read32());
|
2014-07-06 13:03:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-12 20:48:05 +04:00
|
|
|
Frame.prototype.throw = function(ex) {
|
2014-07-06 12:29:36 +04:00
|
|
|
var handler_pc = null;
|
2014-07-11 10:21:12 +04:00
|
|
|
|
2014-07-13 04:51:35 +04:00
|
|
|
for (var i=0; i<this.exception_table.length; i++) {
|
2014-07-12 10:20:45 +04:00
|
|
|
if (this.ip >= this.exception_table[i].start_pc && this.ip <= this.exception_table[i].end_pc) {
|
|
|
|
if (this.exception_table[i].catch_type === 0) {
|
2014-07-12 20:48:05 +04:00
|
|
|
handler_pc = this.exception_table[i].handler_pc;
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-12 10:20:45 +04:00
|
|
|
var name = this.cp[this.cp[this.exception_table[i].catch_type].name_index].bytes;
|
2014-07-13 20:28:19 +04:00
|
|
|
if (name === ex.className) {
|
2014-07-12 10:20:45 +04:00
|
|
|
handler_pc = this.exception_table[i].handler_pc;
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-06 12:29:36 +04:00
|
|
|
if (handler_pc != null) {
|
2014-07-13 01:07:11 +04:00
|
|
|
stack.push(ex);
|
2014-07-12 20:48:05 +04:00
|
|
|
this.ip = handler_pc;
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
|
|
|
throw ex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 11:15:00 +04:00
|
|
|
Frame.prototype.raiseException = function(className, message) {
|
2014-07-13 10:22:17 +04:00
|
|
|
var ex = CLASSES.newObject(this, className);
|
2014-07-14 05:52:31 +04:00
|
|
|
var ctor = CLASSES.getMethod(ex.class, "<init>", "(Ljava/lang/String;)V", false);
|
2014-07-13 10:24:10 +04:00
|
|
|
this.stack.push(ex);
|
|
|
|
this.stack.push(message);
|
2014-07-14 17:45:31 +04:00
|
|
|
this.invoke(OPCODES.invokespecial, ctor);
|
2014-07-12 10:20:45 +04:00
|
|
|
this.throw(ex);
|
2014-07-07 05:16:15 +04:00
|
|
|
}
|
|
|
|
|
2014-07-14 17:45:31 +04:00
|
|
|
Frame.prototype.invoke = function(op, methodInfo) {
|
2014-07-13 11:00:11 +04:00
|
|
|
if (ACCESS_FLAGS.isNative(methodInfo.access_flags)) {
|
|
|
|
NATIVE.invokeNative(this, methodInfo);
|
|
|
|
return;
|
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
|
2014-07-14 06:53:24 +04:00
|
|
|
var consumes = Signature.parse(methodInfo.signature).IN.slots;
|
2014-07-14 17:48:02 +04:00
|
|
|
|
|
|
|
if (op !== OPCODES.invokestatic) {
|
2014-07-14 06:53:24 +04:00
|
|
|
++consumes;
|
2014-07-14 17:48:02 +04:00
|
|
|
var obj = this.stack[this.stack.length - consumes];
|
|
|
|
if (!obj) {
|
|
|
|
this.raiseException("java/lang/NullPointerException");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2014-07-13 02:03:46 +04:00
|
|
|
|
2014-07-13 21:51:34 +04:00
|
|
|
var callee = new Frame(methodInfo);
|
2014-07-13 11:00:11 +04:00
|
|
|
callee.locals = this.stack;
|
2014-07-13 21:51:34 +04:00
|
|
|
callee.localsBase = this.stack.length - consumes;
|
2014-07-13 10:05:35 +04:00
|
|
|
|
2014-07-12 07:20:41 +04:00
|
|
|
while (true) {
|
2014-07-13 11:00:11 +04:00
|
|
|
var op = callee.read8();
|
2014-07-13 21:37:28 +04:00
|
|
|
console.log(callee.methodInfo.classInfo.className, callee.methodInfo.name, callee.ip - 1, OPCODES[op], callee.stack.length);
|
2014-07-12 07:20:41 +04:00
|
|
|
switch (op) {
|
|
|
|
case OPCODES.return:
|
2014-07-13 21:51:34 +04:00
|
|
|
this.stack.length -= consumes;
|
2014-07-13 01:40:38 +04:00
|
|
|
return;
|
2014-07-12 07:20:41 +04:00
|
|
|
|
|
|
|
case OPCODES.ireturn:
|
|
|
|
case OPCODES.freturn:
|
|
|
|
case OPCODES.areturn:
|
2014-07-13 21:51:34 +04:00
|
|
|
this.stack.length -= consumes;
|
2014-07-13 11:00:11 +04:00
|
|
|
this.stack.push(callee.stack.pop());
|
2014-07-13 04:51:35 +04:00
|
|
|
return;
|
2014-07-12 07:20:41 +04:00
|
|
|
|
|
|
|
case OPCODES.lreturn:
|
|
|
|
case OPCODES.dreturn:
|
2014-07-13 21:51:34 +04:00
|
|
|
this.stack.length -= consumes;
|
2014-07-13 11:00:11 +04:00
|
|
|
this.stack.push2(callee.stack.pop2());
|
2014-07-13 04:51:35 +04:00
|
|
|
return;
|
2014-07-12 07:20:41 +04:00
|
|
|
|
|
|
|
default:
|
2014-07-12 22:48:05 +04:00
|
|
|
var opName = OPCODES[op];
|
2014-07-14 02:27:25 +04:00
|
|
|
if (!(opName in this))
|
|
|
|
throw new Error("Opcode " + opName + " [" + op + "] not supported.");
|
2014-07-13 11:00:11 +04:00
|
|
|
callee[opName]();
|
2014-07-12 07:20:41 +04:00
|
|
|
break;
|
|
|
|
}
|
2014-07-06 12:29:36 +04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.nop = function() {
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.aconst_null = function() {
|
|
|
|
this.stack.push(null);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_m1 = function() {
|
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_0 = Frame.prototype.fconst_0 = function() {
|
|
|
|
this.stack.push(0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lconst_0 = Frame.prototype.dconst_0 = function() {
|
|
|
|
this.stack.push2(0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_1 = Frame.prototype.fconst_1 = function() {
|
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lconst_1 = Frame.prototype.dconst_1 = function() {
|
|
|
|
this.stack.push2(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_2 = Frame.prototype.fconst_2 = function() {
|
|
|
|
this.stack.push(2);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_3 = function() {
|
|
|
|
this.stack.push(3);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_4 = function() {
|
|
|
|
this.stack.push(4);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iconst_5 = function() {
|
|
|
|
this.stack.push(5);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.sipush = function() {
|
|
|
|
this.stack.push(this.read16());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.bipush = function() {
|
|
|
|
this.stack.push(this.read8());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ldc = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var constant = this.cp[this.read8()];
|
2014-07-06 12:29:36 +04:00
|
|
|
switch(constant.tag) {
|
2014-07-12 20:48:05 +04:00
|
|
|
case TAGS.CONSTANT_String:
|
2014-07-13 10:22:17 +04:00
|
|
|
this.stack.push(CLASSES.newString(this, this.cp[constant.string_index].bytes));
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Error("not support constant type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ldc_w = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var constant = this.cp[this.read16()];
|
2014-07-06 12:29:36 +04:00
|
|
|
switch(constant.tag) {
|
2014-07-12 20:48:05 +04:00
|
|
|
case TAGS.CONSTANT_String:
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(this.cp[constant.string_index].bytes);
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Error("not support constant type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ldc2_w = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var constant = this.cp[this.read16()];
|
2014-07-06 12:29:36 +04:00
|
|
|
switch(constant.tag) {
|
2014-07-12 20:48:05 +04:00
|
|
|
case TAGS.CONSTANT_String:
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(this.cp[constant.string_index].bytes);
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
case TAGS.CONSTANT_Long:
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(Numeric.getLong(constant.bytes));
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
case TAGS.CONSTANT_Double:
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(constant.bytes.readDoubleBE(0));
|
2014-07-06 12:29:36 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Error("not support constant type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iload = Frame.prototype.iload = Frame.prototype.aload = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var idx = this.isWide() ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(this.getLocal(idx));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lload = Frame.prototype.dload = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var idx = this.isWide() ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(this.getLocal(idx));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iload_0 = Frame.prototype.fload_0 = Frame.prototype.aload_0 = function() {
|
|
|
|
this.stack.push(this.getLocal(0));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lload_0 = Frame.prototype.dloat_0 = function() {
|
|
|
|
this.stack.push2(this.getLocal(0));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iload_1 = Frame.prototype.fload_1 = Frame.prototype.aload_1 = function() {
|
|
|
|
this.stack.push(this.getLocal(1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lload_1 = Frame.prototype.dloat_1 = function() {
|
|
|
|
this.stack.push2(this.getLocal(1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iload_2 = Frame.prototype.fload_2 = Frame.prototype.aload_2 = function() {
|
|
|
|
this.stack.push(this.getLocal(2));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lload_2 = Frame.prototype.dloat_2 = function() {
|
|
|
|
this.stack.push2(this.getLocal(2));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iload_3 = Frame.prototype.fload_3 = Frame.prototype.aload_3 = function() {
|
|
|
|
this.stack.push(this.getLocal(3));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lload_3 = Frame.prototype.dloat_3 = function() {
|
|
|
|
this.stack.push2(this.getLocal(3));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
Frame.prototype.checkArrayAccess = function(refArray, idx) {
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!refArray) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NullPointerException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return false;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-12 20:42:36 +04:00
|
|
|
if (idx < 0 || idx >= refArray.length) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/ArrayIndexOutOfBoundsException", idx);
|
2014-07-12 07:20:41 +04:00
|
|
|
return false;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-12 07:20:41 +04:00
|
|
|
return true;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iaload = Frame.prototype.faload = Frame.prototype.aaload = Frame.prototype.baload = Frame.prototype.caload = Frame.prototype.saload = function() {
|
|
|
|
var idx = this.stack.pop();
|
|
|
|
var refArray = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
if (!this.checkArrayAccess(refArray, idx)) {
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(refArray[idx]);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.laload = Frame.prototype.daload = function() {
|
|
|
|
var idx = this.stack.pop();
|
|
|
|
var refArray = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
if (!this.checkArrayAccess(refArray, idx)) {
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(refArray[idx]);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.istore = Frame.prototype.fstore = Frame.prototype.astore = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var idx = this.isWide() ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.setLocal(idx, this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lstore = Frame.prototype.dstore = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var idx = this.isWide() ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.setLocal(idx, this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.istore_0 = Frame.prototype.fstore_0 = Frame.prototype.astore_0 = function() {
|
|
|
|
this.setLocal(0, this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lstore_0 = Frame.prototype.dstore_0 = function() {
|
|
|
|
this.setLocal(0, this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.istore_1 = Frame.prototype.fstore_1 = Frame.prototype.astore_1 = function() {
|
|
|
|
this.setLocal(1, this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lstore_1 = Frame.prototype.dstore_1 = function() {
|
|
|
|
this.setLocal(1, this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.istore_2 = Frame.prototype.fstore_2 = Frame.prototype.astore_2 = function() {
|
|
|
|
this.setLocal(2, this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lstore_2 = Frame.prototype.dstore_2 = function() {
|
|
|
|
this.setLocal(2, this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.istore_3 = Frame.prototype.fstore_3 = Frame.prototype.astore_3 = function() {
|
|
|
|
this.setLocal(3, this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lstore_3 = Frame.prototype.dstore_3 = function() {
|
|
|
|
this.setLocal(3, this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iastore = Frame.prototype.fastore = Frame.prototype.aastore = Frame.prototype.bastore = Frame.prototype.castore = Frame.prototype.sastore = function() {
|
|
|
|
var val = this.stack.pop();
|
|
|
|
var idx = this.stack.pop();
|
|
|
|
var refArray = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
if (!this.checkArrayAccess(refArray, idx)) {
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-07 05:16:15 +04:00
|
|
|
refArray[idx] = val;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lastore = Frame.prototype.dastore = function() {
|
|
|
|
var val = this.stack.pop2();
|
|
|
|
var idx = this.stack.pop();
|
|
|
|
var refArray = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
if (!this.checkArrayAccess(refArray, idx)) {
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-07 05:16:15 +04:00
|
|
|
refArray[idx] = val;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.pop = function() {
|
|
|
|
this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.pop2 = function() {
|
|
|
|
this.stack.pop2();
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup = function() {
|
|
|
|
var val = this.stack.pop();
|
|
|
|
this.stack.push(val);
|
|
|
|
this.stack.push(val);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup_x1 = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup_x2 = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
var val3 = this.stack.pop();
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val3);
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup2 = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup2_x1 = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
var val3 = this.stack.pop();
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val3);
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dup2_x2 = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
var val3 = this.stack.pop();
|
|
|
|
var val4 = this.stack.pop();
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val4);
|
|
|
|
this.stack.push(val3);
|
|
|
|
this.stack.push(val2);
|
|
|
|
this.stack.push(val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.swap = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val1);
|
|
|
|
this.stack.push(val2);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iinc = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var wide = this.isWide();
|
|
|
|
var idx = wide ? this.read16() : this.read8();
|
|
|
|
var val = wide ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.setLocal(idx, this.getLocal(idx) + val);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iadd = function() {
|
|
|
|
this.stack.push((this.stack.pop() + this.stack.pop())|0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ladd = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().add(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dadd = function() {
|
|
|
|
this.stack.push2(this.stack.pop2() + this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fadd = function() {
|
|
|
|
this.stack.push(utils.double2float(this.stack.pop() + this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.isub = function() {
|
|
|
|
this.stack.push((- this.stack.pop() + this.stack.pop())|0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lsub = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().add(this.stack.pop2()).negate());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dsub = function() {
|
|
|
|
this.stack.push2(- this.stack.pop2() + this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fsub = function() {
|
|
|
|
this.stack.push(utils.double2float(- this.stack.pop() + this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.imul = function() {
|
|
|
|
this.stack.push(Math.imul(this.stack.pop(), this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lmul = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().multiply(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dmul = function() {
|
|
|
|
this.stack.push2(this.stack.pop2() * this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fmul = function() {
|
|
|
|
this.stack.push(utils.double2float(this.stack.pop() * this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.idiv = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
2014-07-12 07:20:41 +04:00
|
|
|
if (!val1) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/ArithmeticException", "/ by zero");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push((val2 === utils.INT_MIN && val1 === -1) ? val2 : ((a / b)|0));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ldiv = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
2014-07-12 07:20:41 +04:00
|
|
|
if (!val1.isZero()) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/ArithmeticException", "/ by zero");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(val2.div(val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ddiv = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
|
|
|
this.stack.push2(val2 / val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fdiv = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(utils.double2float(val2 / val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.irem = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
2014-07-12 07:20:41 +04:00
|
|
|
if (!val1) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/ArithmeticException", "/ by zero");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(val2 % val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lrem = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
2014-07-12 07:20:41 +04:00
|
|
|
if (val1.isZero()) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/ArithmeticException", "/ by zero");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push2(val2.modulo(val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.drem = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
|
|
|
this.stack.push2(val2 % val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.frem = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(utils.double2float(val2 % val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ineg = function() {
|
|
|
|
this.stack.push((- this.stack.pop())|0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lneg = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().negate());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dneg = function() {
|
|
|
|
this.stack.push2(- this.stack.pop2());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fneg = function() {
|
|
|
|
this.stack.push(- this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ishl = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val2 << val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lshl = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
|
|
|
this.stack.push2(val2.shiftLeft(val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ishr = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val2 >> val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lshr = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
|
|
|
this.stack.push2(val2.shiftRight(val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iushr = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
|
|
|
this.stack.push(val2 >>> val1);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lushr = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
|
|
|
this.stack.push2(val2.shiftRightUnsigned(val1));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iand = function() {
|
|
|
|
this.stack.push(this.stack.pop() & this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.land = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().and(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ior = function() {
|
|
|
|
this.stack.push(this.stack.pop() | this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lor = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().or(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ixor = function() {
|
|
|
|
this.stack.push(this.stack.pop() ^ this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lxor = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().xor(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lcmp = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
2014-07-12 07:20:41 +04:00
|
|
|
if (val2.greaterThan(val1)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-12 07:20:41 +04:00
|
|
|
} else if (val2.lessThan(val1)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(0);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fcmpl = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (isNaN(val1) || isNaN(val2)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 > val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 < val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(0);
|
2014-07-12 20:48:05 +04:00
|
|
|
}
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.fcmpg = function() {
|
|
|
|
var val1 = this.stack.pop();
|
|
|
|
var val2 = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (isNaN(val1) || isNaN(val2)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 > val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 < val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(0);
|
2014-07-12 20:48:05 +04:00
|
|
|
}
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dcmpl = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (isNaN(val1) || isNaN(val2)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 > val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 < val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(0);
|
2014-07-12 20:48:05 +04:00
|
|
|
}
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.dcmpg = function() {
|
|
|
|
var val1 = this.stack.pop2();
|
|
|
|
var val2 = this.stack.pop2();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (isNaN(val1) || isNaN(val2)) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 > val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else if (val2 < val1) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(-1);
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(0);
|
2014-07-12 20:48:05 +04:00
|
|
|
}
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.newarray = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var type = this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
var size = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (size < 0) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NegativeSizeException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-14 04:36:47 +04:00
|
|
|
this.stack.push(CLASSES.newArray(this, ARRAY_TYPE[type], size));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.anewarray = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
2014-07-12 20:48:05 +04:00
|
|
|
var className = this.cp[this.cp[idx].name_index].bytes;
|
2014-07-13 10:05:35 +04:00
|
|
|
var size = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (size < 0) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NegativeSizeException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(new Array(size));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.multianewarray = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
2014-07-12 20:48:05 +04:00
|
|
|
var type = this.cp[this.cp[idx].name_index].bytes;
|
2014-07-12 10:20:45 +04:00
|
|
|
var dimensions = this.read8();
|
2014-07-06 12:29:36 +04:00
|
|
|
var lengths = new Array(dimensions);
|
|
|
|
for(var i=0; i<dimensions; i++) {
|
2014-07-13 10:05:35 +04:00
|
|
|
lengths[i] = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
var createMultiArray = function(lengths) {
|
|
|
|
if (lengths.length === 0) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var length = lengths.shift();
|
|
|
|
var array = new Array(length);
|
|
|
|
for (var i=0; i<length; i++) {
|
|
|
|
array[i] = createMultiArray(lengths);
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
};
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(createMultiArray(lengths));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.arraylength = function() {
|
|
|
|
var ref = this.stack.pop();
|
|
|
|
this.stack.push(ref.length);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmpeq = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 === ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmpne = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 !== ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmpgt = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 < ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmple = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() >= this.stack.pop() ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmplt = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() > this.stack.pop() ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_icmpge = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 <= ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_acmpeq = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 === ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.if_acmpne = function() {
|
2014-07-12 20:48:05 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
var ref1 = this.stack.pop();
|
|
|
|
var ref2 = this.stack.pop();
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = ref1 !== ref2 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifne = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() !== 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifeq = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() === 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.iflt = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() < 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifge = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() >= 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifgt = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() > 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifle = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.ip - 1 + this.read16signed();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.stack.pop() <= 0 ? jmp : this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2l = function() {
|
|
|
|
this.stack.push2(new gLong(this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2f = function() {
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2d = function() {
|
|
|
|
this.stack.push2(this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2b = function() {
|
|
|
|
this.stack.push((this.stack.pop() << 24) >> 24);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2c = function() {
|
|
|
|
this.stack.push(this.stack.pop() & 0xffff);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.i2s = function() {
|
|
|
|
this.stack.push((this.stack.pop() << 16) >> 16);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.l2i = function() {
|
|
|
|
this.stack.push(this.stack.pop2().toInt());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.l2d = function() {
|
|
|
|
this.stack.push2(this.stack.pop2().toNumber());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.l2f = function() {
|
|
|
|
this.stack.push(utils.double2float(this.stack.pop2().toNumber()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.d2i = function() {
|
|
|
|
this.stack.push(utils.double2int(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.d2l = function() {
|
|
|
|
this.stack.push2(utils.double2long(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.d2f = function() {
|
|
|
|
this.stack.push(utils.double2float(this.stack.pop2()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.f2d = function() {
|
|
|
|
this.stack.push2(this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.f2i = function() {
|
|
|
|
this.stack.push(utils.double2int(this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.f2l = function() {
|
|
|
|
this.stack.push2(gLong.fromNumber(this.stack.pop()));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.goto = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip += this.read16signed() - 1;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.goto_w = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip += this.read32signed() - 1;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifnull = function() {
|
|
|
|
var ref = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!ref) {
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip += this.read16signed() - 1;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ifnonnull = function() {
|
|
|
|
var ref = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!!ref) {
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip += this.read16signed() - 1;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.putfield = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
2014-07-12 20:48:05 +04:00
|
|
|
var fieldName = this.cp[this.cp[this.cp[idx].name_and_type_index].name_index].bytes;
|
2014-07-13 10:05:35 +04:00
|
|
|
var val = this.stack.pop();
|
|
|
|
var obj = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!obj) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NullPointerException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-07 05:16:15 +04:00
|
|
|
obj[fieldName] = val;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.getfield = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var cp = this.cp;
|
|
|
|
var nameAndType = cp[cp[this.read16()].name_and_type_index];
|
2014-07-11 10:21:12 +04:00
|
|
|
var fieldName = cp[nameAndType.name_index].bytes;
|
2014-07-13 10:05:35 +04:00
|
|
|
var obj = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!obj) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NullPointerException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-11 10:21:12 +04:00
|
|
|
var value = obj[fieldName];
|
|
|
|
if (typeof value === "undefined") {
|
|
|
|
value = util.defaultValue(cp[nameAndType.signature_index].bytes);
|
2014-07-09 12:07:14 +04:00
|
|
|
}
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(value);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.new = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
2014-07-12 20:48:05 +04:00
|
|
|
var className = this.cp[this.cp[idx].name_index].bytes;
|
2014-07-13 10:22:17 +04:00
|
|
|
this.stack.push(CLASSES.newObject(this, className));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.getstatic = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
|
|
|
var className = this.cp[this.cp[this.cp[idx].class_index].name_index].bytes;
|
|
|
|
var fieldName = this.cp[this.cp[this.cp[idx].name_and_type_index].name_index].bytes;
|
2014-07-13 10:22:17 +04:00
|
|
|
this.stack.push(CLASSES.getStaticField(this, className, fieldName));
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.putstatic = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
|
|
|
var className = this.cp[this.cp[this.cp[idx].class_index].name_index].bytes;
|
|
|
|
var fieldName = this.cp[this.cp[this.cp[idx].name_and_type_index].name_index].bytes;
|
2014-07-13 10:22:17 +04:00
|
|
|
CLASSES.setStaticField(this, className, fieldName, this.stack.pop());
|
2014-07-13 01:07:11 +04:00
|
|
|
}
|
|
|
|
|
2014-07-14 05:40:05 +04:00
|
|
|
Frame.prototype.invokestatic = Frame.prototype.invokevirtual = Frame.prototype.invokespecial = Frame.prototype.invokeinterface = function() {
|
|
|
|
var op = this.getOp();
|
2014-07-13 01:07:11 +04:00
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
2014-07-09 11:12:58 +04:00
|
|
|
|
2014-07-14 05:40:05 +04:00
|
|
|
if (op === OPCODES.invokeinterface) {
|
|
|
|
var argsNumber = this.read8();
|
|
|
|
var zero = this.read8();
|
|
|
|
}
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-14 05:41:08 +04:00
|
|
|
var cp = this.cp;
|
2014-07-14 05:50:53 +04:00
|
|
|
|
2014-07-14 05:41:08 +04:00
|
|
|
var className = cp[cp[cp[idx].class_index].name_index].bytes;
|
|
|
|
var methodName = cp[cp[cp[idx].name_and_type_index].name_index].bytes;
|
|
|
|
var signature = cp[cp[cp[idx].name_and_type_index].signature_index].bytes;
|
2014-07-06 12:29:36 +04:00
|
|
|
|
2014-07-14 05:50:53 +04:00
|
|
|
var classInfo = CLASSES.getClass(this, className);
|
2014-07-14 05:52:31 +04:00
|
|
|
var method = CLASSES.getMethod(classInfo, methodName, signature, op === OPCODES.invokestatic);
|
2014-07-13 01:07:11 +04:00
|
|
|
|
2014-07-14 17:45:31 +04:00
|
|
|
this.invoke(op, method);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.jsr = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.read16();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(this.ip);
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = jmp;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.jsr_w = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.read32();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(this.ip);
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = jmp;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.ret = function() {
|
2014-07-12 22:54:04 +04:00
|
|
|
var idx = this.isWide() ? this.read16() : this.read8();
|
2014-07-13 10:05:35 +04:00
|
|
|
this.ip = this.getLocal(idx);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.tableswitch = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var startip = this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
var jmp;
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
while ((this.ip % 4) != 0) {
|
|
|
|
this.ip++;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
var def = this.read32();
|
|
|
|
var low = this.read32();
|
|
|
|
var high = this.read32();
|
2014-07-13 10:05:35 +04:00
|
|
|
var val = this.stack.pop();
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-06 12:29:36 +04:00
|
|
|
if (val < low || val > high) {
|
|
|
|
jmp = def;
|
|
|
|
} else {
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip += (val - low) << 2;
|
2014-07-12 20:48:05 +04:00
|
|
|
jmp = this.read32();
|
|
|
|
}
|
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = startip - 1 + this.u32_to_s32(jmp);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.lookupswitch = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var startip = this.ip;
|
2014-07-06 12:29:36 +04:00
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
while ((this.ip % 4) != 0) {
|
|
|
|
this.ip++;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
var jmp = this.read32();
|
|
|
|
var size = this.read32();
|
2014-07-13 10:05:35 +04:00
|
|
|
var val = this.stack.pop();
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-06 12:29:36 +04:00
|
|
|
lookup:
|
|
|
|
for(var i=0; i<size; i++) {
|
2014-07-12 10:20:45 +04:00
|
|
|
var key = this.read32();
|
|
|
|
var offset = this.read32();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (key === val) {
|
|
|
|
jmp = offset;
|
|
|
|
}
|
|
|
|
if (key >= val) {
|
2014-07-12 20:48:05 +04:00
|
|
|
break lookup;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
}
|
2014-07-12 20:48:05 +04:00
|
|
|
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip = startip - 1 + this.u32_to_s32(jmp);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.instanceof = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
|
|
|
var className = this.cp[this.cp[idx].name_index].bytes;
|
2014-07-13 10:05:35 +04:00
|
|
|
var obj = this.stack.pop();
|
2014-07-13 20:28:19 +04:00
|
|
|
this.stack.push(obj.class.className === className);
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.checkcast = function() {
|
2014-07-12 10:20:45 +04:00
|
|
|
var idx = this.read16();
|
|
|
|
var type = this.cp[this.cp[idx].name_index].bytes;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.athrow = function() {
|
|
|
|
this.throw(this.stack.pop());
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.wide = function() {
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.monitorenter = function() {
|
|
|
|
var obj = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!obj) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NullPointerException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-07 05:16:15 +04:00
|
|
|
}
|
|
|
|
if (obj.hasOwnProperty("$lock$")) {
|
2014-07-13 10:05:35 +04:00
|
|
|
this.stack.push(obj);
|
2014-07-12 10:20:45 +04:00
|
|
|
this.ip--;
|
|
|
|
// SCHEDULER.yield();
|
2014-07-06 12:29:36 +04:00
|
|
|
} else {
|
|
|
|
obj["$lock$"] = "locked";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-13 10:05:35 +04:00
|
|
|
Frame.prototype.monitorexit = function() {
|
|
|
|
var obj = this.stack.pop();
|
2014-07-06 12:29:36 +04:00
|
|
|
if (!obj) {
|
2014-07-13 11:15:00 +04:00
|
|
|
this.raiseException("java/lang/NullPointerException");
|
2014-07-12 07:20:41 +04:00
|
|
|
return;
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|
2014-07-07 05:16:15 +04:00
|
|
|
delete obj["$lock$"];
|
2014-07-12 10:20:45 +04:00
|
|
|
// SCHEDULER.yield();
|
2014-07-06 12:29:36 +04:00
|
|
|
}
|