numeric abstractions completed

This commit is contained in:
Artur Ventura 2011-07-18 00:56:41 +01:00
parent 3ea052a707
commit 97c1b8669f
7 changed files with 167 additions and 58 deletions

20
cpu.js
View File

@ -14,13 +14,26 @@
#define JVM_THROWS_NEW(exception) throw "VER: throws new exception" #define JVM_THROWS_NEW(exception) throw "VER: throws new exception"
#ifdef DEBUG_INTRP #ifdef DEBUG_INTRP
#define LOG_INTRP(x) LOG(x) #define LOG_INTRP(x) LOG(x)
#define DEFALIAS(opx) case opx: if(temp!=null) { temp = pc + ": opx" }
#else #else
#define LOG_INTRP(x) #define LOG_INTRP(x)
#define DEFALIAS(opx) case opx:
#endif #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 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){ function canonicalName(ref){
return ref.str.replace(/\//g,".") return ref.str.replace(/\//g,".")
} }
@ -104,7 +117,10 @@ function interpret(frame){
var local_variables = frame.local_variables; var local_variables = frame.local_variables;
var code = 0; //resolve code from method; var code = 0; //resolve code from method;
switch(opcode){ #ifdef DEBUG_INTRP
var temp = null;
#endif
switch(OPCODE){
#include "intrp.js" #include "intrp.js"
} }
} }

186
intrp.js
View File

@ -9,9 +9,11 @@
* *
*/ */
#include "opcodes.js"
DEFOP(AALOAD) DEFOP(AALOAD)
var index = operand_stack.pop(); var index = OPPOP();
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
if (arrayref == NULL){ if (arrayref == NULL){
JVM_THROWS_NEW(java.lang.NullPointerException); JVM_THROWS_NEW(java.lang.NullPointerException);
@ -19,13 +21,13 @@ DEFOP(AALOAD)
if (index >= arrayref.length){ if (index >= arrayref.length){
JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException);
} }
operand_stack.push(arrayref.value[index.value]); OPPUSH(arrayref.value[index.value]);
ENDDEF ENDDEF
DEFOP(AASTORE) DEFOP(AASTORE)
var value = operand_stack.pop(); var value = OPPOP();
var index = operand_stack.pop(); var index = OPPOP();
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
if (arrayref == NULL){ if (arrayref == NULL){
JVM_THROWS_NEW(java.lang.NullPointerException); JVM_THROWS_NEW(java.lang.NullPointerException);
@ -39,59 +41,61 @@ DEFOP(AASTORE)
ENDDEF ENDDEF
DEFOP(ACONST_NULL) DEFOP(ACONST_NULL)
operand_stack.push(null); OPPUSH(null);
ENDDEF ENDDEF
DEFOP(ALOAD) DEFOP(ALOAD)
var i = operand_stack.pop(); var i = OPPOP();
operand_stack.push(local_variables[i]) OPPUSH(LOCAL_VAR(i))
ENDDEF ENDDEF
DEFOP(ALOAD_0) DEFALIAS(ALOAD_0)
DEFOP(ALOAD_1) DEFALIAS(ALOAD_1)
DEFOP(ALOAD_2) DEFALIAS(ALOAD_2)
DEFOP(ALOAD_3) DEFALIAS(ALOAD_3)
operand_stack.push(local_variables[opcode - 0x2a]); DEFNOP()
OPPUSH(LOCAL_VAR(OPCODE - ALOAD_0));
ENDDEF ENDDEF
DEFOP(ANEWARRAY) DEFOP(ANEWARRAY)
var indexbyte1 = code.pop(); var indexbyte1 = READ_NEXT();
var indexbyte2 = code.pop(); var indexbyte2 = READ_NEXT();
var count = operand_stack.pop(); var count = OPPOP();
if (count < 0){ if (count < 0){
JVM_THROWS_NEW(java.lang.NegativeArraySizeException); JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
} }
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2); var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
var instance = {length:count, value:[], classRef:this.jvm.classForName(clRef)}; var instance = {length:count, value:[], 'class':this.jvm.classForName(clRef)};
operand_stack.push(instance); OPPUSH(instance);
ENDDEF ENDDEF
DEFOP(ARETURN) DEFOP(ARETURN)
var objectref = operand_stack.pop(); var objectref = OPPOP();
return {return_object: objectref} return {return_object: objectref}
ENDDEF ENDDEF
DEFOP(ARRAYLENGTH) DEFOP(ARRAYLENGTH)
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
operand_stack.push(arrayref.length); OPPUSH(arrayref.length);
ENDDEF ENDDEF
DEFOP(ASTORE) DEFOP(ASTORE)
var objectref = operand_stack.pop(); var objectref = OPPOP();
local_variables[code.pop()] = objectref; LOCAL_VAR(READ_NEXT()) = objectref;
ENDDEF ENDDEF
DEFOP(ASTORE_0) DEFALIAS(ASTORE_0)
DEFOP(ASTORE_1) DEFALIAS(ASTORE_1)
DEFOP(ASTORE_2) DEFALIAS(ASTORE_2)
DEFOP(ASTORE_3) DEFALIAS(ASTORE_3)
var objectref = operand_stack.pop(); DEFNOP()
local_variables[opcode-0x4b] = objectref; var objectref = OPPOP();
LOCAL_VAR(OPCODE-ASTORE_0) = objectref;
ENDDEF ENDDEF
DEFOP(ATHROW) DEFOP(ATHROW)
var objectref = operand_stack.pop(); var objectref = OPPOP();
if (objectref == null){ if (objectref == null){
JVM_THROWS_NEW(java.lang.NullPointerException); JVM_THROWS_NEW(java.lang.NullPointerException);
} }
@ -99,9 +103,9 @@ DEFOP(ATHROW)
ENDDEF ENDDEF
DEFOP(BALOAD) DEFOP(BALOAD)
var value = operand_stack.pop(); var value = OPPOP();
var index = operand_stack.pop(); var index = OPPOP();
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
if (arrayref == NULL){ if (arrayref == NULL){
JVM_THROWS_NEW(java.lang.NullPointerException); JVM_THROWS_NEW(java.lang.NullPointerException);
@ -113,21 +117,20 @@ DEFOP(BALOAD)
ENDDEF ENDDEF
DEFOP(BIPUSH) DEFOP(BIPUSH)
operand_stack.push(code.pop()); OPPUSH(code.pop());
ENDDEF ENDDEF
DEFOP(CALOAD) DEFOP(CALOAD)
var index = operand_stack.pop(); var index = OPPOP();
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
operand_stack.push(arrayref.value[index]); OPPUSH(arrayref.value[index]);
ENDDEF ENDDEF
DEFOP(CASTORE) DEFOP(CASTORE)
var value = operand_stack.pop(); var value = OPPOP();
var index = operand_stack.pop(); var index = OPPOP();
var arrayref = operand_stack.pop(); var arrayref = OPPOP();
if (arrayref == NULL){ if (arrayref == NULL){
JVM_THROWS_NEW(java.lang.NullPointerException); JVM_THROWS_NEW(java.lang.NullPointerException);
@ -139,31 +142,112 @@ DEFOP(CASTORE)
ENDDEF ENDDEF
DEFOP(CHECKCAST) DEFOP(CHECKCAST)
var objectref = operand_stack.pop(); var objectref = OPPOP();
var indexbyte1 = code.pop(); var indexbyte1 = READ_NEXT();
var indexbyte2 = code.pop(); var indexbyte2 = READ_NEXT();
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2); var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
if (objectref.classRef.isAssignable(clRef)){ if (objectref.classRef.isAssignable(clRef)){
operand_stack.push(objectref); OPPUSH(objectref);
}else{ }else{
JVM_THROWS_NEW(java.lang.ClassCastException); JVM_THROWS_NEW(java.lang.ClassCastException);
} }
ENDDEF ENDDEF
DEFOP(D2F) 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 ENDDEF
DEFOP(D2F) DEFOP(D2I)
PANIC("Not Implemented Yet"); 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 ENDDEF
DEFOP(D2L) 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 ENDDEF
DEFOP(DADD) 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 ENDDEF
DEFOP(DALOAD) 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

BIN
lib/compiler.jar Normal file

Binary file not shown.

View File

@ -9,7 +9,8 @@
* *
*/ */
var DataStream = function(data){ /** @constructor */
function DataStream(data){
this.i = 0; this.i = 0;
this.getF = function(size){ this.getF = function(size){

View File

@ -27,6 +27,7 @@
#include "infos.js" #include "infos.js"
#include "class.js" #include "class.js"
#include "cpu.js" #include "cpu.js"
#include "types.js"
var test_jvm; var test_jvm;

View File

@ -9,6 +9,9 @@
* *
*/ */
#ifndef _TYPES_JS_
#define _TYPES_JS_
#define NOP 0 #define NOP 0
#define ACONST_NULL 1 #define ACONST_NULL 1
#define ICONST_M1 2 #define ICONST_M1 2
@ -210,3 +213,5 @@
#define IFNONNULL 199 #define IFNONNULL 199
#define GOTO_W 200 #define GOTO_W 200
#define JSR_W 201 #define JSR_W 201
#endif // _TYPES_JS_

View File

@ -9,6 +9,9 @@
* *
*/ */
#ifndef _TYPES_JS_
#define _TYPES_JS_
// Local Variables Types // Local Variables Types
#define LOC_VAR_boolean 0x001; #define LOC_VAR_boolean 0x001;
#define LOC_VAR_byte 0x002; #define LOC_VAR_byte 0x002;
@ -61,7 +64,6 @@
#define LONG_OVERFLOW(value) ((value % (2*LONG_USIZE)) - (LONG_USIZE)) #define LONG_OVERFLOW(value) ((value % (2*LONG_USIZE)) - (LONG_USIZE))
#define POSITIVE_INF Number.POSITIVE_INFINITY #define POSITIVE_INF Number.POSITIVE_INFINITY
#define NEGATIVE_INF Number.NEGATIVE_INFINITY #define NEGATIVE_INF Number.NEGATIVE_INFINITY
#define NAN NaN
#define IS_OVERFLOW(value,mark) (value > mark) #define IS_OVERFLOW(value,mark) (value > mark)
#define IS_UNDERFLOW(value,mark) (value < mark) #define IS_UNDERFLOW(value,mark) (value < mark)
@ -86,6 +88,6 @@ function getRefClass(ref){
return ref.classRef; return ref.classRef;
} }
} }
#endif //_TYPES_JS_