preliminary attr interpretation

This commit is contained in:
Artur Ventura 2011-07-03 12:51:20 +01:00
parent 50b18121b3
commit 2afcb5bce3
5 changed files with 199 additions and 69 deletions

48
attributes.js Normal file
View File

@ -0,0 +1,48 @@
var Attributes_table = {
ConstantValue: function(){
this.read = function(dStream, constantPool){
this.constantvalue = ConstantPoolRef(dStream.getU2(), constantPool);
switch(this.constantvalue.id){
case CONSTANT_Long:
case CONSTANT_Float:
case CONSTANT_Double:
case CONSTANT_Integer:
case CONSTANT_String:
return;
default:
throw "ConstantValue Attr points to wrong constant value, got " + constTagName(this.constantvalue.id);
}
}
},
Code: function(){
this.read = function(dStream, constantPool){
}
}
};
function UnkownAttr(){
this.read = function(dStream){
this.info = [];
for(var i=0; i<attribute_length; i++){
this.info[i] = dStream.getU1();
}
}
}
var Attribute = function(dStream, constantPool){
var attribute_name = ConstantPoolRef(dStream.getU2(), constantPool, CONSTANT_Utf8);
var action = Attributes_table[attribute_name.str];
var result;
if (action){
result = new action();
}else{
result = new UnkownAttr();
}
result.attribute_name = attribute_name;
result.attribute_length = dStream.getU4();
result.read(dStream, constantPool);
}

View File

@ -57,12 +57,6 @@ var constUtf8 = function(){
return this;
};
var constDummy = function(){
this.read = function (stream){};
return this;
}
var constInt = function(){
this.value = null;
this.id = CONSTANT_Integer;
@ -103,7 +97,14 @@ var constClass = function(){
this.name_index = null;
this.id = CONSTANT_Class;
this.read = function(dStream){
this.name_index = dstream.getU2();
this.name_index = dStream.getU2();
}
this.set_ref = function(pool){
var ref = pool[this.name_index - 1];
if (!ref || ref.id != CONSTANT_Utf8){
throw "Class name index doesn't point to Utf8 in the Constant Pool";
}
this.name_ref = ref;
}
};
@ -111,15 +112,14 @@ var constString = function(){
this.string_index = null;
this.id = CONSTANT_String;
this.read = function(dStream){
this.string_index = dstream.getU2();
this.string_index = dStream.getU2();
}
};
var constString = function(){
this.string_index = null;
this.id = CONSTANT_String;
this.read = function(dStream){
this.string_index = dstream.getU2();
this.set_ref = function(pool){
var ref = pool[this.string_index - 1];
if (!ref && ref.id != CONSTANT_Utf8){
throw "String index doesn't point to Utf8 in the Constant Pool";
}
this.string_ref = ref;
}
};
@ -130,6 +130,19 @@ var constRef = function(){
this.class_index = dStream.getU2();
this.name_and_type_index = dStream.getU2();
};
this.set_ref = function(pool){
var classRef = pool[this.class_index - 1];
if (!classRef || classRef.id != CONSTANT_Class){
throw constTagName(this.id) + " class index doesn't point to Class in the Constant Pool";
}
this.class_ref = classRef;
var nAiRef = pool[this.name_and_type_index - 1];
if (!nAiRef || nAiRef.id != CONSTANT_NameAndType){
throw constTagName(this.id) + " name and type index doesn't point to Name and Type in the Constant Pool, got " + constTagName(nAiRef.id);
}
this.name_and_type_ref = nAiRef;
}
};
var constFieldRef = function(){
@ -158,6 +171,19 @@ var constName_and_Type_info = function(){
this.name_index = dStream.getU2();
this.descriptor_index = dStream.getU2();
};
this.set_ref = function(pool){
var nameRef = pool[this.name_index - 1];
if (!nameRef || nameRef.id != CONSTANT_Utf8){
throw "Name_and_Type name index doesn't point to Utf8 in the Constant Pool";
}
this.name_ref = nameRef;
var descriptorRef = pool[this.descriptor_index - 1];
if(!descriptorRef || descriptorRef.id != CONSTANT_Utf8){
throw "Name_and_Type descriptior index doesn't point to Utf8 in the Constant Pool";
}
this.descriptor_ref = descriptorRef;
}
}
@ -199,9 +225,80 @@ var allocConstEntry = function(tag){
obj = new constName_and_Type_info();
break;
default:
obj = new constDummy();
//throw "allocConstEntry: bad tag value = " + tag;
throw "allocConstEntry: bad tag value = " + tag;
break;
} // switch
return obj;
}
var ConstantPool = function(dStream){
this.constantPoolCount = dStream.getU2();
this.constantPool = [];
for(var i = 1; i < this.constantPoolCount; i++){
var tag = dStream.getU1();
log(constTagName(tag));
var alloc = allocConstEntry(tag);
alloc.read(dStream);
this.constantPool[(i-1)] = alloc;
if (alloc.id == CONSTANT_Long || alloc.id == CONSTANT_Double) {
log("next");
i++;
this.constantPool[(i-1)] = null;
}
}
for(var i = 1; i < this.constantPoolCount; i++){
var obj = this.constantPool[(i-1)];
if (obj.set_ref){
obj.set_ref(this.constantPool);
}
}
}
var constTagName = function (info){
switch(info){
case 7:
return "Class";
case 9:
return "FieldRef";
case 10:
return "MethodRef";
case 11:
return "InterfaceMethodRef";
case 8:
return "String";
case 3:
return "Integer";
case 4:
return "Float";
case 5:
return "Long";
case 6:
return "Double";
case 12:
return "NameAndType";
case 1:
return "Utf8";
default:
return "??0x" + info.toString(16) + "??";
}
return null;
}
var ConstantPoolRef = function(index, constantPool, expected){
var result = constantPool.constantPool[index - 1];
if (expected && result.id != expected){
throw "ConstantPoolRef: ref was expected to be " + constTagName(expected) + " but at " + index + " there's a " + constTagName(result.id);
}
return result;
}

8
fieldInfo.js Normal file
View File

@ -0,0 +1,8 @@
var FieldInfo = function(dStream){
this.access_flags = dStream.getU2();
this.name_index = dStream.getU2();
this.descriptor_index = dStream.getU2();
this.attributes_count = dStream.getU2();
// VER: attributes must be restricted.
this.attributes = [];
}

View File

@ -34,7 +34,7 @@
</head>
<body onload="main()">
<h1>JS JVM</h1>
Open JavaScript Debug Window to read the debug;
Debug:
<pre id="log"></pre>
</body>
</html>

79
main.js
View File

@ -2,6 +2,17 @@
include("linearDataStream.js");
include("constantPool.js");
// access flags DEFINE
var ACC_PUBLIC = 0x0001; // Declared public; may be accessed from outside its package.
var ACC_PRIVATE = 0x0002; // Declared private; usable only within the defining class.
var ACC_PROTECTED = 0x0004; // Declared protected; may be accessed within subclasses.
var ACC_STATIC = 0x0008; // Declared static.
var ACC_FINAL = 0x0010; // Declared final; no subclasses allowed.
var ACC_SUPER = 0x0020; // Treat superclass methods specially when invoked by the invokespecial instruction.
var ACC_VOLATILE = 0x0040; // Declared volatile; cannot be cached.
var ACC_INTERFACE = 0x0200; // Is an interface, not a class.
var ACC_ABSTRACT = 0x0400; // Declared abstract; may not be instantiated.
var ACC_TRANSIENT = 0x0080; // Declared transient; not written or read by a persistent object manager.
function slurpFile (filename, fa) {
var xmlHttpRequest, response, result ;
@ -44,49 +55,6 @@ log = function (msg){
}
}
ConstantPoolStruct = function (tag,info){
log("0x" + tag.toString(16))
switch(tag){
case 7:
log("Class: "+ info.toString(16));
break;
case 9:
log("FieldRef: "+ info.toString(16));
break;
case 10:
log("MethodRef: "+ info.toString(16));
break;
case 11:
log("InterfaceMethodRef: "+ info.toString(16));
break;
case 8:
log("String: " + info.toString(16));
break;
case 3:
log("Integer: " + info.toString(16));
break;
case 4:
log("Float: " + info.toString(16));
break;
case 5:
log("Long: " + info.toString(16));
break;
case 6:
log("Long: " + info.toString(16));
break;
case 12:
log("NameAndType: " + info.toString(16));
break;
case 1:
log("Utf8: " + info.toString(16));
break;
default:
throw "Unkown tag number 0x" + tag.toString(16);
}
this.tag = tag;
this.info = info;
};
ClassDefinition = function (file){
var dataStream = new DataStream(slurpFile(file)[1]);
this.magic = dataStream.getU4();
@ -94,16 +62,25 @@ ClassDefinition = function (file){
throw "Invalid Class Magic (" + this.magic + ")" ;
}
this.minorVersion = dataStream.getU2();
this.majorVersion = dataStream.getU2();
this.constantPoolCount = dataStream.getU2();
this.constantPool = [];
for(var i = 1; i <= this.constantPoolCount; i++){
var tag = dataStream.getU1();
// new ConstantPoolStruct(tag,0);
var alloc = allocConstEntry(tag);
alloc.read(dataStream);
this.constantPool[(i-1)] = alloc;
if (this.majorVersion > 50 || this.majorVersion < 45){
throw "Unsuported java class file format version";
}
this.constantPool = new ConstantPool(dataStream);
this.access_flags = dataStream.getU2();
this.this_class = ConstantPoolRef(dataStream.getU2(), this.constantPool,CONSTANT_Class);
this.super_class = ConstantPoolRef(dataStream.getU2(), this.constantPool,CONSTANT_Class);
this.interface_count = dataStream.getU2();
// VER: interfaces refs must be classes
this.interfaces = [];
for(var i=0; i<this.interface_count; i++){
this.interfaces[i] = ConstantPoolRef(dataStream.getU2(), this.constantPool,CONSTANT_Class);
}
this.fields_count = dataStream.getU2();
}
function main (args){