preliminary attr interpretation
This commit is contained in:
parent
50b18121b3
commit
2afcb5bce3
48
attributes.js
Normal file
48
attributes.js
Normal 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);
|
||||
}
|
131
constantPool.js
131
constantPool.js
@ -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
8
fieldInfo.js
Normal 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 = [];
|
||||
}
|
@ -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
79
main.js
@ -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){
|
||||
|
Loading…
x
Reference in New Issue
Block a user