First Version to Run Bytecode
This commit is contained in:
parent
d8d15c1a12
commit
f0049c7725
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "constantPool.jsh"
|
#include "constantPool.jsh"
|
||||||
|
#include "attributes.jsh"
|
||||||
|
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
var ExceptionTableEntry = function(dStream, constantPool){
|
var ExceptionTableEntry = function(dStream, constantPool){
|
||||||
@ -56,6 +57,7 @@ var LocalVariableTableEntry = function(dStream, constantPool){
|
|||||||
var Attributes_table = {
|
var Attributes_table = {
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
ConstantValue: function(){
|
ConstantValue: function(){
|
||||||
|
this.id = ATTR_CONSTANT_VALUE;
|
||||||
this.read = function(dStream, constantPool){
|
this.read = function(dStream, constantPool){
|
||||||
this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool);
|
this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool);
|
||||||
switch(this.constantvalue.id){
|
switch(this.constantvalue.id){
|
||||||
@ -73,6 +75,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
Code: function(){
|
Code: function(){
|
||||||
|
this.id = ATTR_CODE;
|
||||||
this.read = function(dStream, constantPool){
|
this.read = function(dStream, constantPool){
|
||||||
this.max_stack = dStream.getU2();
|
this.max_stack = dStream.getU2();
|
||||||
this.max_locals = dStream.getU2();
|
this.max_locals = dStream.getU2();
|
||||||
@ -110,6 +113,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
Exceptions: function(){
|
Exceptions: function(){
|
||||||
|
this.id = ATTR_EXCEPTIONS;
|
||||||
this.read = function(dStream, constantPool){
|
this.read = function(dStream, constantPool){
|
||||||
this.number_of_exceptions = dStream.getU2();
|
this.number_of_exceptions = dStream.getU2();
|
||||||
this.exception_table = [];
|
this.exception_table = [];
|
||||||
@ -120,6 +124,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
InnerClasses: function(){
|
InnerClasses: function(){
|
||||||
|
this.id = ATTR_INNER_CLASSES;
|
||||||
this.read = function(dStream, constantPool){
|
this.read = function(dStream, constantPool){
|
||||||
this.number_of_classes = dStream.getU2();
|
this.number_of_classes = dStream.getU2();
|
||||||
this.classes = [];
|
this.classes = [];
|
||||||
@ -130,6 +135,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
Synthetic: function(){
|
Synthetic: function(){
|
||||||
|
this.id = ATTR_SYNTHETIC;
|
||||||
this.read = function(dStream,constantPool){
|
this.read = function(dStream,constantPool){
|
||||||
if (this.attribute_length != 0){
|
if (this.attribute_length != 0){
|
||||||
throw "Synthetic Attr length not 0";
|
throw "Synthetic Attr length not 0";
|
||||||
@ -138,12 +144,14 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
SourceFile: function(){
|
SourceFile: function(){
|
||||||
|
this.id = ATTR_SOURCE_FILE;
|
||||||
this.read = function(dStream,constantPool){
|
this.read = function(dStream,constantPool){
|
||||||
this.soucefile = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Utf8);
|
this.soucefile = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Utf8);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
LineNumberTable: function(){
|
LineNumberTable: function(){
|
||||||
|
this.id = ATTR_LINE_NUMBER_TABLE;
|
||||||
this.read = function(dStream,constantPool){
|
this.read = function(dStream,constantPool){
|
||||||
this.line_number_table_length = dStream.getU2();
|
this.line_number_table_length = dStream.getU2();
|
||||||
this.line_number_table = [];
|
this.line_number_table = [];
|
||||||
@ -154,6 +162,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
LocalVariableTable: function(){
|
LocalVariableTable: function(){
|
||||||
|
this.id = ATTR_LOCAL_VARIABLE_TABLE;
|
||||||
this.read=function(dStream,constantPool){
|
this.read=function(dStream,constantPool){
|
||||||
this.local_variable_table_length = dStream.getU2();
|
this.local_variable_table_length = dStream.getU2();
|
||||||
this.local_variable_table = [];
|
this.local_variable_table = [];
|
||||||
@ -164,6 +173,7 @@ var Attributes_table = {
|
|||||||
},
|
},
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
Deprecated: function(){
|
Deprecated: function(){
|
||||||
|
this.id = ATTR_DEPRECATED;
|
||||||
this.read = function(dStream,constantPool){
|
this.read = function(dStream,constantPool){
|
||||||
if (this.attribute_length != 0){
|
if (this.attribute_length != 0){
|
||||||
throw "Synthetic Attr length not 0";
|
throw "Synthetic Attr length not 0";
|
||||||
@ -173,6 +183,7 @@ var Attributes_table = {
|
|||||||
};
|
};
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
function UnkownAttr(){
|
function UnkownAttr(){
|
||||||
|
this.id = ATTR_UNKOWNATTR;
|
||||||
this.read = function(dStream){
|
this.read = function(dStream){
|
||||||
this.info = [];
|
this.info = [];
|
||||||
for(var i=0; i<this.attribute_length; i++){
|
for(var i=0; i<this.attribute_length; i++){
|
||||||
|
30
src/cpu.js
30
src/cpu.js
@ -66,8 +66,13 @@ var JVM = function(params,args){
|
|||||||
this.java_lang_cloneable = this.classForName("java.lang.Cloneable");
|
this.java_lang_cloneable = this.classForName("java.lang.Cloneable");
|
||||||
this.java_io_serializable = this.classForName("java.io.Serializable");
|
this.java_io_serializable = this.classForName("java.io.Serializable");
|
||||||
this.java_lang_string = this.classForName("java.lang.String");
|
this.java_lang_string = this.classForName("java.lang.String");
|
||||||
this.mainClass = this.args[0];
|
this.main_class = this.classForName(this.args[0])
|
||||||
this.classForName(this.mainClass).makeInstance();
|
this.main_class.initializeClass();
|
||||||
|
var method = this.main_class["method main([Ljava/lang/String;)V"];
|
||||||
|
if (method == null){
|
||||||
|
PANIC(this.args[0] + " doesn't have a a main method");
|
||||||
|
}
|
||||||
|
method.invoke(null,this.main_class);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
@ -86,20 +91,29 @@ function JVMPanic(message){
|
|||||||
this.toString = function(){
|
this.toString = function(){
|
||||||
return "JVMPanic: " + message
|
return "JVMPanic: " + message
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function interpret(frame){
|
function interpret(frame,code,method,xl){
|
||||||
var operand_stack = frame.operand_stack;
|
var operand_stack = frame.operand_stack;
|
||||||
var local_variables = frame.local_variables;
|
var local_variables = frame.local_variables;
|
||||||
var code = 0; //resolve code from method;
|
|
||||||
var opcode;
|
var opcode;
|
||||||
var pc;
|
var pc = 0;
|
||||||
var xl;
|
|
||||||
|
|
||||||
#ifdef DEBUG_INTRP
|
#ifdef DEBUG_INTRP
|
||||||
var temp = null;
|
var temp = null;
|
||||||
#endif
|
#endif
|
||||||
|
while(pc < code.length){
|
||||||
|
opcode = READ_NEXT();
|
||||||
switch(OPCODE){
|
switch(OPCODE){
|
||||||
#include "intrp.def"
|
#include "intrp.def"
|
||||||
|
default:
|
||||||
|
PANIC("Invalid OPCODE " + opcode);
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_INTRP
|
||||||
|
temp = null;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
PANIC("PC overran CODE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#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" }
|
#define DEFALIAS(opx) case opx: if(!temp) { temp = pc + ": opx op:[" + operand_stack + "] lvar:[" + local_variables + "]"; }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define LOG_INTRP(x)
|
#define LOG_INTRP(x)
|
||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#define PANIC(msg) throw new JVMPanic(msg)
|
#define PANIC(msg) throw new JVMPanic(msg)
|
||||||
|
|
||||||
#define DEFOP(opx) case opx: LOG_INTRP(pc + ": opx");
|
#define DEFOP(opx) case opx: LOG_INTRP(pc + ": opx op:[" + operand_stack + "] lvar:[" + local_variables + "]");
|
||||||
#define DEFNOP() LOG_INTRP(temp)
|
#define DEFNOP() LOG_INTRP(temp)
|
||||||
#define ENDDEF break;
|
#define ENDDEF break;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@
|
|||||||
#define OPCODE opcode
|
#define OPCODE opcode
|
||||||
#define PC pc
|
#define PC pc
|
||||||
#define STACK_MOVE(y,x) OPSTACK(OPSTACK_LENGTH()-y) = OPSTACK(OPSTACK_LENGTH()-x)
|
#define STACK_MOVE(y,x) OPSTACK(OPSTACK_LENGTH()-y) = OPSTACK(OPSTACK_LENGTH()-x)
|
||||||
#define READ_NEXT() code[++pc]
|
#define READ_NEXT() code[pc++]
|
||||||
|
|
||||||
#define CHECK_NULL(ref) if (ref == NULL){ JVM_THROWS_NEW(java.lang.NullPointerException); }
|
#define CHECK_NULL(ref) if (ref == NULL){ JVM_THROWS_NEW(java.lang.NullPointerException); }
|
||||||
#define CHECK_ARRAY_INDEX(ind,ref) if (ind >= ref.length){ JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); }
|
#define CHECK_ARRAY_INDEX(ind,ref) if (ind >= ref.length){ JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); }
|
||||||
|
@ -43,4 +43,13 @@ var MethodInfo = function(dStream, constantPool){
|
|||||||
for (var i=0; i<this.attributes_count; i++){
|
for (var i=0; i<this.attributes_count; i++){
|
||||||
this.attributes[i] = Attribute(dStream,constantPool);
|
this.attributes[i] = Attribute(dStream,constantPool);
|
||||||
}
|
}
|
||||||
|
this.invoke = function (self,xl){
|
||||||
|
var frame = { operand_stack: [], local_variables:[] };
|
||||||
|
for (var i=0; i<this.attributes_count; i++){
|
||||||
|
var attr = this.attributes[i];
|
||||||
|
if (attr.id == ATTR_CODE){
|
||||||
|
interpret(frame,attr.code,this,xl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ DEFOP(BALOAD)
|
|||||||
ENDDEF
|
ENDDEF
|
||||||
|
|
||||||
DEFOP(BIPUSH)
|
DEFOP(BIPUSH)
|
||||||
OPPUSH(code.pop());
|
OPPUSH(READ_NEXT());
|
||||||
ENDDEF
|
ENDDEF
|
||||||
|
|
||||||
DEFOP(CALOAD)
|
DEFOP(CALOAD)
|
||||||
@ -925,7 +925,7 @@ DEFOP(INVOKESTATIC)
|
|||||||
PANIC("NOT IMPLEMENTED YET");
|
PANIC("NOT IMPLEMENTED YET");
|
||||||
ENDDEF
|
ENDDEF
|
||||||
|
|
||||||
DEFOP(INVOKESTATIC)
|
DEFOP(INVOKEVIRTUAL)
|
||||||
var indexbyte1 = READ_NEXT();
|
var indexbyte1 = READ_NEXT();
|
||||||
var indexbyte2 = READ_NEXT();
|
var indexbyte2 = READ_NEXT();
|
||||||
var args = [];
|
var args = [];
|
||||||
@ -999,7 +999,7 @@ DEFALIAS(ISTORE_1)
|
|||||||
DEFALIAS(ISTORE_2)
|
DEFALIAS(ISTORE_2)
|
||||||
DEFALIAS(ISTORE_3)
|
DEFALIAS(ISTORE_3)
|
||||||
DEFNOP()
|
DEFNOP()
|
||||||
LOCAL_VAR(READ_NEXT()) = (OPCODE - ISTORE_0);
|
LOCAL_VAR(OPCODE - ISTORE_0) = OPPOP();
|
||||||
ENDDEF
|
ENDDEF
|
||||||
|
|
||||||
DEFOP(ISUB)
|
DEFOP(ISUB)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user