First Version to Run Bytecode

This commit is contained in:
Artur Ventura 2011-08-03 00:32:54 +01:00
parent d8d15c1a12
commit f0049c7725
5 changed files with 48 additions and 14 deletions

View File

@ -10,6 +10,7 @@
*/
#include "constantPool.jsh"
#include "attributes.jsh"
/** @constructor */
var ExceptionTableEntry = function(dStream, constantPool){
@ -56,6 +57,7 @@ var LocalVariableTableEntry = function(dStream, constantPool){
var Attributes_table = {
/** @constructor */
ConstantValue: function(){
this.id = ATTR_CONSTANT_VALUE;
this.read = function(dStream, constantPool){
this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool);
switch(this.constantvalue.id){
@ -73,6 +75,7 @@ var Attributes_table = {
},
/** @constructor */
Code: function(){
this.id = ATTR_CODE;
this.read = function(dStream, constantPool){
this.max_stack = dStream.getU2();
this.max_locals = dStream.getU2();
@ -110,6 +113,7 @@ var Attributes_table = {
},
/** @constructor */
Exceptions: function(){
this.id = ATTR_EXCEPTIONS;
this.read = function(dStream, constantPool){
this.number_of_exceptions = dStream.getU2();
this.exception_table = [];
@ -120,6 +124,7 @@ var Attributes_table = {
},
/** @constructor */
InnerClasses: function(){
this.id = ATTR_INNER_CLASSES;
this.read = function(dStream, constantPool){
this.number_of_classes = dStream.getU2();
this.classes = [];
@ -130,6 +135,7 @@ var Attributes_table = {
},
/** @constructor */
Synthetic: function(){
this.id = ATTR_SYNTHETIC;
this.read = function(dStream,constantPool){
if (this.attribute_length != 0){
throw "Synthetic Attr length not 0";
@ -138,12 +144,14 @@ var Attributes_table = {
},
/** @constructor */
SourceFile: function(){
this.id = ATTR_SOURCE_FILE;
this.read = function(dStream,constantPool){
this.soucefile = ConstantPoolRef(dStream.getU2(), constantPool,CONSTANT_Utf8);
}
},
/** @constructor */
LineNumberTable: function(){
this.id = ATTR_LINE_NUMBER_TABLE;
this.read = function(dStream,constantPool){
this.line_number_table_length = dStream.getU2();
this.line_number_table = [];
@ -154,6 +162,7 @@ var Attributes_table = {
},
/** @constructor */
LocalVariableTable: function(){
this.id = ATTR_LOCAL_VARIABLE_TABLE;
this.read=function(dStream,constantPool){
this.local_variable_table_length = dStream.getU2();
this.local_variable_table = [];
@ -164,6 +173,7 @@ var Attributes_table = {
},
/** @constructor */
Deprecated: function(){
this.id = ATTR_DEPRECATED;
this.read = function(dStream,constantPool){
if (this.attribute_length != 0){
throw "Synthetic Attr length not 0";
@ -173,6 +183,7 @@ var Attributes_table = {
};
/** @constructor */
function UnkownAttr(){
this.id = ATTR_UNKOWNATTR;
this.read = function(dStream){
this.info = [];
for(var i=0; i<this.attribute_length; i++){

View File

@ -66,8 +66,13 @@ var JVM = function(params,args){
this.java_lang_cloneable = this.classForName("java.lang.Cloneable");
this.java_io_serializable = this.classForName("java.io.Serializable");
this.java_lang_string = this.classForName("java.lang.String");
this.mainClass = this.args[0];
this.classForName(this.mainClass).makeInstance();
this.main_class = this.classForName(this.args[0])
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 */
@ -86,20 +91,29 @@ function JVMPanic(message){
this.toString = function(){
return "JVMPanic: " + message
}
};
}
function interpret(frame){
function interpret(frame,code,method,xl){
var operand_stack = frame.operand_stack;
var local_variables = frame.local_variables;
var code = 0; //resolve code from method;
var opcode;
var pc;
var xl;
var pc = 0;
#ifdef DEBUG_INTRP
var temp = null;
#endif
while(pc < code.length){
opcode = READ_NEXT();
switch(OPCODE){
#include "intrp.def"
default:
PANIC("Invalid OPCODE " + opcode);
}
#ifdef DEBUG_INTRP
temp = null;
#endif
}
PANIC("PC overran CODE");
}

View File

@ -16,7 +16,7 @@
#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" }
#define DEFALIAS(opx) case opx: if(!temp) { temp = pc + ": opx op:[" + operand_stack + "] lvar:[" + local_variables + "]"; }
#else
#define LOG_INTRP(x)
@ -25,7 +25,7 @@
#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 ENDDEF break;
@ -42,7 +42,7 @@
#define OPCODE opcode
#define PC pc
#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_ARRAY_INDEX(ind,ref) if (ind >= ref.length){ JVM_THROWS_NEW(java.lang.ArrayIndexOutOfBoundsException); }

View File

@ -43,4 +43,13 @@ var MethodInfo = function(dStream, constantPool){
for (var i=0; i<this.attributes_count; i++){
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);
}
}
}
}

View File

@ -109,7 +109,7 @@ DEFOP(BALOAD)
ENDDEF
DEFOP(BIPUSH)
OPPUSH(code.pop());
OPPUSH(READ_NEXT());
ENDDEF
DEFOP(CALOAD)
@ -925,7 +925,7 @@ DEFOP(INVOKESTATIC)
PANIC("NOT IMPLEMENTED YET");
ENDDEF
DEFOP(INVOKESTATIC)
DEFOP(INVOKEVIRTUAL)
var indexbyte1 = READ_NEXT();
var indexbyte2 = READ_NEXT();
var args = [];
@ -999,7 +999,7 @@ DEFALIAS(ISTORE_1)
DEFALIAS(ISTORE_2)
DEFALIAS(ISTORE_3)
DEFNOP()
LOCAL_VAR(READ_NEXT()) = (OPCODE - ISTORE_0);
LOCAL_VAR(OPCODE - ISTORE_0) = OPPOP();
ENDDEF
DEFOP(ISUB)