numeric abstractions completed
This commit is contained in:
parent
3ea052a707
commit
97c1b8669f
20
cpu.js
20
cpu.js
@ -14,13 +14,26 @@
|
||||
#define JVM_THROWS_NEW(exception) throw "VER: throws new exception"
|
||||
#ifdef DEBUG_INTRP
|
||||
#define LOG_INTRP(x) LOG(x)
|
||||
#define DEFALIAS(opx) case opx: if(temp!=null) { temp = pc + ": opx" }
|
||||
#else
|
||||
#define LOG_INTRP(x)
|
||||
#define DEFALIAS(opx) case opx:
|
||||
#endif
|
||||
|
||||
#define DEFOP(opcode) case opcode: LOG_INTRP("opcode pc: " + pc);
|
||||
#define DEFOP(opx) case opx: LOG_INTRP(pc + ": opx");
|
||||
#define DEFNOP() LOG_INTRP(temp);
|
||||
#define ENDDEF break;
|
||||
|
||||
#define OPPOP() operand_stack.pop()
|
||||
#define OPPUSH(v) operand_stack.push(v)
|
||||
|
||||
#define LOCAL_VAR(v) local_variables[v]
|
||||
#define OPCODE opcode
|
||||
#define PC pc
|
||||
#define READ_NEXT() code[++pc]
|
||||
|
||||
|
||||
|
||||
function canonicalName(ref){
|
||||
return ref.str.replace(/\//g,".")
|
||||
}
|
||||
@ -104,7 +117,10 @@ function interpret(frame){
|
||||
var local_variables = frame.local_variables;
|
||||
var code = 0; //resolve code from method;
|
||||
|
||||
switch(opcode){
|
||||
#ifdef DEBUG_INTRP
|
||||
var temp = null;
|
||||
#endif
|
||||
switch(OPCODE){
|
||||
#include "intrp.js"
|
||||
}
|
||||
}
|
188
intrp.js
188
intrp.js
@ -9,9 +9,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opcodes.js"
|
||||
|
||||
DEFOP(AALOAD)
|
||||
var index = operand_stack.pop();
|
||||
var arrayref = operand_stack.pop();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
@ -19,13 +21,13 @@ DEFOP(AALOAD)
|
||||
if (index >= arrayref.length){
|
||||
JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException);
|
||||
}
|
||||
operand_stack.push(arrayref.value[index.value]);
|
||||
OPPUSH(arrayref.value[index.value]);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(AASTORE)
|
||||
var value = operand_stack.pop();
|
||||
var index = operand_stack.pop();
|
||||
var arrayref = operand_stack.pop();
|
||||
var value = OPPOP();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
@ -39,59 +41,61 @@ DEFOP(AASTORE)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ACONST_NULL)
|
||||
operand_stack.push(null);
|
||||
OPPUSH(null);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ALOAD)
|
||||
var i = operand_stack.pop();
|
||||
operand_stack.push(local_variables[i])
|
||||
var i = OPPOP();
|
||||
OPPUSH(LOCAL_VAR(i))
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ALOAD_0)
|
||||
DEFOP(ALOAD_1)
|
||||
DEFOP(ALOAD_2)
|
||||
DEFOP(ALOAD_3)
|
||||
operand_stack.push(local_variables[opcode - 0x2a]);
|
||||
DEFALIAS(ALOAD_0)
|
||||
DEFALIAS(ALOAD_1)
|
||||
DEFALIAS(ALOAD_2)
|
||||
DEFALIAS(ALOAD_3)
|
||||
DEFNOP()
|
||||
OPPUSH(LOCAL_VAR(OPCODE - ALOAD_0));
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ANEWARRAY)
|
||||
var indexbyte1 = code.pop();
|
||||
var indexbyte2 = code.pop();
|
||||
var count = operand_stack.pop();
|
||||
var indexbyte1 = READ_NEXT();
|
||||
var indexbyte2 = READ_NEXT();
|
||||
var count = OPPOP();
|
||||
if (count < 0){
|
||||
JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
|
||||
}
|
||||
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
var instance = {length:count, value:[], classRef:this.jvm.classForName(clRef)};
|
||||
operand_stack.push(instance);
|
||||
var instance = {length:count, value:[], 'class':this.jvm.classForName(clRef)};
|
||||
OPPUSH(instance);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ARETURN)
|
||||
var objectref = operand_stack.pop();
|
||||
var objectref = OPPOP();
|
||||
return {return_object: objectref}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ARRAYLENGTH)
|
||||
var arrayref = operand_stack.pop();
|
||||
operand_stack.push(arrayref.length);
|
||||
var arrayref = OPPOP();
|
||||
OPPUSH(arrayref.length);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ASTORE)
|
||||
var objectref = operand_stack.pop();
|
||||
local_variables[code.pop()] = objectref;
|
||||
var objectref = OPPOP();
|
||||
LOCAL_VAR(READ_NEXT()) = objectref;
|
||||
ENDDEF
|
||||
|
||||
DEFOP(ASTORE_0)
|
||||
DEFOP(ASTORE_1)
|
||||
DEFOP(ASTORE_2)
|
||||
DEFOP(ASTORE_3)
|
||||
var objectref = operand_stack.pop();
|
||||
local_variables[opcode-0x4b] = objectref;
|
||||
DEFALIAS(ASTORE_0)
|
||||
DEFALIAS(ASTORE_1)
|
||||
DEFALIAS(ASTORE_2)
|
||||
DEFALIAS(ASTORE_3)
|
||||
DEFNOP()
|
||||
var objectref = OPPOP();
|
||||
LOCAL_VAR(OPCODE-ASTORE_0) = objectref;
|
||||
ENDDEF
|
||||
|
||||
|
||||
DEFOP(ATHROW)
|
||||
var objectref = operand_stack.pop();
|
||||
var objectref = OPPOP();
|
||||
if (objectref == null){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
}
|
||||
@ -99,9 +103,9 @@ DEFOP(ATHROW)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(BALOAD)
|
||||
var value = operand_stack.pop();
|
||||
var index = operand_stack.pop();
|
||||
var arrayref = operand_stack.pop();
|
||||
var value = OPPOP();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
@ -113,21 +117,20 @@ DEFOP(BALOAD)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(BIPUSH)
|
||||
operand_stack.push(code.pop());
|
||||
OPPUSH(code.pop());
|
||||
ENDDEF
|
||||
|
||||
DEFOP(CALOAD)
|
||||
var index = operand_stack.pop();
|
||||
var arrayref = operand_stack.pop();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
|
||||
operand_stack.push(arrayref.value[index]);
|
||||
OPPUSH(arrayref.value[index]);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(CASTORE)
|
||||
var value = operand_stack.pop();
|
||||
var index = operand_stack.pop();
|
||||
var arrayref = operand_stack.pop();
|
||||
|
||||
var value = OPPOP();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
@ -139,31 +142,112 @@ DEFOP(CASTORE)
|
||||
ENDDEF
|
||||
|
||||
DEFOP(CHECKCAST)
|
||||
var objectref = operand_stack.pop();
|
||||
var indexbyte1 = code.pop();
|
||||
var indexbyte2 = code.pop();
|
||||
var objectref = OPPOP();
|
||||
var indexbyte1 = READ_NEXT();
|
||||
var indexbyte2 = READ_NEXT();
|
||||
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
||||
if (objectref.classRef.isAssignable(clRef)){
|
||||
operand_stack.push(objectref);
|
||||
OPPUSH(objectref);
|
||||
}else{
|
||||
JVM_THROWS_NEW(java.lang.ClassCastException);
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(D2F)
|
||||
PANIC("Not Implemented Yet");
|
||||
var value = OPPOP();
|
||||
if (isNaN(value)){
|
||||
OPPUSH(NaN);
|
||||
}else if(IS_OVERFLOW(value,FLOAT_MAX_VALUE)){
|
||||
OPPUSH(POSITIVE_INF);
|
||||
}else if (IS_UNDEFLOW(value,FLOAT_MIN_VALUE)){
|
||||
OPPUSH(NEGATIVE_INF);
|
||||
}else{
|
||||
OPPUSH(value);
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(D2F)
|
||||
PANIC("Not Implemented Yet");
|
||||
DEFOP(D2I)
|
||||
var value = OPPOP();
|
||||
if (isNaN(value)){
|
||||
OPPUSH(0);
|
||||
}else if(IS_OVERFLOW(value,INT_MAX_VALUE)){
|
||||
OPPUSH(INT_MAX_VALUE);
|
||||
}else if(IS_UNDERFLOW(value,INT_MIN_VALUE)){
|
||||
OPPUSH(INT_MIN_VALUE);
|
||||
}else{
|
||||
OPPUSH(Math.round(value));
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(D2L)
|
||||
PANIC("Not Implemented Yet");
|
||||
var value = OPPOP();
|
||||
if (isNaN(value)){
|
||||
OPPUSH(0);
|
||||
}else if(IS_OVERFLOW(value,LONG_MAX_VALUE)){
|
||||
OPPUSH(LONG_MAX_VALUE);
|
||||
}else if(IS_UNDERFLOW(value,LONG_MIN_VALUE)){
|
||||
OPPUSH(LONG_MIN_VALUE);
|
||||
}else{
|
||||
OPPUSH(Math.round(value));
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(DADD)
|
||||
PANIC("Not Implemented Yet");
|
||||
var value1 = OPPOP();
|
||||
var value2 = OPPOP();
|
||||
var result = value1 + value2;
|
||||
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
||||
OPPUSH(POSITIVE_INF);
|
||||
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
||||
OPPUSH(NEGATIVE_INF);
|
||||
}else{
|
||||
OPPUSH(result);
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFOP(DALOAD)
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
}
|
||||
if (index >= arrayref.length){
|
||||
JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException);
|
||||
}
|
||||
OPPUSH(arrayref.value[index]);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(DASTORE)
|
||||
var value = OPPOP();
|
||||
var index = OPPOP();
|
||||
var arrayref = OPPOP();
|
||||
if (arrayref == NULL){
|
||||
JVM_THROWS_NEW(java.lang.NullPointerException);
|
||||
}
|
||||
if (index >= arrayref.length){
|
||||
JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException);
|
||||
}
|
||||
arrayref.value[index] = value;
|
||||
ENDDEF
|
||||
|
||||
DEFALIAS(DCMPG)
|
||||
DEFALIAS(DCMPL)
|
||||
DEFNOP()
|
||||
var value2 = OPPOP();
|
||||
var value1 = OPPOP();
|
||||
if (isNaN(value1) || isNaN(value2)) { OPPUSH((OPCODE == DCMPG)?1:0)}
|
||||
if (value1 > value2){
|
||||
OPPUSH(1);
|
||||
}else if(value1 == value2){
|
||||
OPPUSH(0);
|
||||
}else{
|
||||
OPPUSH(-1);
|
||||
}
|
||||
ENDDEF
|
||||
|
||||
DEFALIAS(DCONST_1)
|
||||
DEFALIAS(DCONST_0)
|
||||
DEFNOP()
|
||||
OPPUSH(OPCODE-DCONST_0);
|
||||
ENDDEF
|
||||
|
||||
DEFOP(DALOAD)
|
BIN
lib/compiler.jar
Normal file
BIN
lib/compiler.jar
Normal file
Binary file not shown.
@ -8,8 +8,9 @@
|
||||
* Author: Artur Ventura
|
||||
*
|
||||
*/
|
||||
|
||||
var DataStream = function(data){
|
||||
|
||||
/** @constructor */
|
||||
function DataStream(data){
|
||||
this.i = 0;
|
||||
|
||||
this.getF = function(size){
|
||||
|
1
main.js
1
main.js
@ -27,6 +27,7 @@
|
||||
#include "infos.js"
|
||||
#include "class.js"
|
||||
#include "cpu.js"
|
||||
#include "types.js"
|
||||
|
||||
|
||||
var test_jvm;
|
||||
|
@ -8,6 +8,9 @@
|
||||
* Author: Artur Ventura
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_JS_
|
||||
#define _TYPES_JS_
|
||||
|
||||
#define NOP 0
|
||||
#define ACONST_NULL 1
|
||||
@ -210,3 +213,5 @@
|
||||
#define IFNONNULL 199
|
||||
#define GOTO_W 200
|
||||
#define JSR_W 201
|
||||
|
||||
#endif // _TYPES_JS_
|
6
types.js
6
types.js
@ -8,6 +8,9 @@
|
||||
* Author: Artur Ventura
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_JS_
|
||||
#define _TYPES_JS_
|
||||
|
||||
// Local Variables Types
|
||||
#define LOC_VAR_boolean 0x001;
|
||||
@ -61,7 +64,6 @@
|
||||
#define LONG_OVERFLOW(value) ((value % (2*LONG_USIZE)) - (LONG_USIZE))
|
||||
#define POSITIVE_INF Number.POSITIVE_INFINITY
|
||||
#define NEGATIVE_INF Number.NEGATIVE_INFINITY
|
||||
#define NAN NaN
|
||||
|
||||
#define IS_OVERFLOW(value,mark) (value > mark)
|
||||
#define IS_UNDERFLOW(value,mark) (value < mark)
|
||||
@ -86,6 +88,6 @@ function getRefClass(ref){
|
||||
return ref.classRef;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //_TYPES_JS_
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user