-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: jvilk <jvilk@cs.umass.edu>
- Loading branch information
jvilk
committed
May 28, 2012
0 parents
commit 794adca
Showing
2,798 changed files
with
8,065 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,347 @@ | ||
/** | ||
* Object for the entire constant pool for a class. | ||
*/ | ||
function ConstantPool(javaClassReader) { | ||
//This global is used by the parsing process as a convenient location | ||
//for getting constant pool data. | ||
CONSTANTPOOL = this; | ||
|
||
/** | ||
* METHODS | ||
*/ | ||
|
||
/** | ||
* Get the string from a UTF8 info object at the given index. | ||
* Asserts that it is, in fact, a UTF8 info object. | ||
*/ | ||
this.getUTF8Info = function(index) { | ||
if (index == 0) return undefined; | ||
assert(this[index].tag == ConstantPoolInfo.tags.UTF8); | ||
return this[index].string; | ||
}; | ||
|
||
/** | ||
* Resolve a class info object at the given index to its UTF8 name. | ||
* Asserts that it is, in fact, a class info object. | ||
*/ | ||
this.getClassInfo = function(index) { | ||
if (index == 0) return undefined; | ||
if (!(index in this)) assert(false); | ||
assert(this[index].tag == ConstantPoolInfo.tags.CLASS); | ||
return this[index].name; | ||
}; | ||
|
||
/** | ||
* Print the constant pool contents to the terminal. | ||
*/ | ||
this.print = function() { | ||
addTextToConsole("Constant Pool Contents:"); | ||
for (var i = 1; i < this.count; i++) | ||
{ | ||
addTextToConsole("\t" + i + " "); | ||
this[i].print(); | ||
} | ||
}; | ||
|
||
/** | ||
* PARSING | ||
*/ | ||
|
||
//u2 constant_pool_count; | ||
this.count = javaClassReader.getUintField(2); | ||
//cp_info constant_pool[constant_pool_count-1]; | ||
//NOTE: Index 0 of the constant pool is reserved for use by the JVM, and is not | ||
//in the class file. | ||
for(var i = 1; i < this.count; i++) { | ||
var tag = javaClassReader.getUintField(1); | ||
|
||
switch(tag) { | ||
case ConstantPoolInfo.tags.CLASS: | ||
var name_index = javaClassReader.getUintField(2); | ||
this[i] = new ConstantClassInfo(name_index); | ||
break; | ||
case ConstantPoolInfo.tags.FIELDREF: | ||
case ConstantPoolInfo.tags.METHODREF: | ||
case ConstantPoolInfo.tags.INTERFACEMETHODREF: | ||
var class_index = javaClassReader.getUintField(2); | ||
var name_and_type_index = javaClassReader.getUintField(2); | ||
this[i] = new ConstantRefInfo(tag, class_index, name_and_type_index); | ||
break; | ||
case ConstantPoolInfo.tags.STRING: | ||
var string_index = javaClassReader.getUintField(2); | ||
this[i] = new ConstantStringInfo(string_index); | ||
break; | ||
case ConstantPoolInfo.tags.INTEGER: | ||
var bytes = new Integer(javaClassReader.getIntField(4)); | ||
this[i] = new ConstantNumberInfo(tag, bytes); | ||
break; | ||
case ConstantPoolInfo.tags.FLOAT: | ||
var bytes = new Float(javaClassReader.getFloatField(4)); | ||
this[i] = new ConstantNumberInfo(tag, bytes); | ||
break; | ||
case ConstantPoolInfo.tags.LONG: | ||
var high = javaClassReader.getUintField(4); | ||
var low = javaClassReader.getUintField(4); | ||
var long_value = new Long(low, high); | ||
this[i] = new ConstantBigNumberInfo(tag, long_value); | ||
//8 byte constants take up two slots. | ||
i++ | ||
break; | ||
case ConstantPoolInfo.tags.DOUBLE: | ||
var double_field = new Double(javaClassReader.getDoubleField(8)); | ||
this[i] = new ConstantBigNumberInfo(tag, double_field); | ||
//8 byte constants take up two slots. | ||
i++; | ||
break; | ||
case ConstantPoolInfo.tags.NAMEANDTYPE: | ||
var name_index = javaClassReader.getUintField(2); | ||
var descriptor_index = javaClassReader.getUintField(2); | ||
this[i] = new ConstantNameAndTypeInfo(name_index, descriptor_index); | ||
break; | ||
case ConstantPoolInfo.tags.UTF8: | ||
var length = javaClassReader.getUintField(2); | ||
var string = javaClassReader.getUTF8Field(length); | ||
this[i] = new ConstantUTF8Info(length, string); | ||
break; | ||
default: | ||
addErrorToConsole("ERROR: Unable to determine the 'tag' element of a cp_info struct: " + tag + "."); | ||
break; | ||
} | ||
} | ||
|
||
//Constant pool items sometimes refer to other constant pool items, and | ||
//we cannot resolve these references until the constant pool is completely | ||
//assembled. So, we do it after the fact. | ||
for (var i = 1; i < this.count; i++) | ||
{ | ||
if (i in this) //This may be false for the second items for double/long constants. | ||
{ | ||
this[i].resolveReferences(this); | ||
} | ||
} | ||
} | ||
|
||
/*The parent object for all the Constant Pool objects | ||
*Paramaters | ||
* tagType - What type is this information for | ||
*/ | ||
function ConstantPoolInfo(tagType) { | ||
this.tag = tagType; | ||
//Part of the "interface" of this type. Resolves references to the constant pool to objects. | ||
this.resolveReferences = function(constantPool) { }; | ||
this.print = function() { }; | ||
} | ||
|
||
ConstantPoolInfo.tags = { | ||
CLASS : 7, | ||
FIELDREF : 9, | ||
METHODREF : 10, | ||
INTERFACEMETHODREF : 11, | ||
STRING : 8, | ||
INTEGER : 3, | ||
FLOAT : 4, | ||
LONG : 5, | ||
DOUBLE : 6, | ||
NAMEANDTYPE : 12, | ||
UTF8 : 1 | ||
}; | ||
|
||
/* Represents a constant_pool_class_info. | ||
* parameters: | ||
* nameIndex - The index into the constant pool that represents the class | ||
*/ | ||
function ConstantClassInfo(nameIndex) { | ||
inherits(this,"ConstantPoolInfo", ConstantPoolInfo.tags.CLASS); | ||
this.nameIndex = nameIndex; | ||
//Index into the constant pool for the class 'u2' | ||
|
||
//Resolve all references to other constant pool objects. | ||
this.resolveReferences = function(constantPool) { | ||
this.name = CONSTANTPOOL.getUTF8Info(this.nameIndex); | ||
}; | ||
|
||
this.print = function() { | ||
addTextToCurrentLine("class " + this.name); | ||
}; | ||
} | ||
|
||
/* Represents a constant_pool_info for FieldRef, MethodRef, or InterfaceMethodRef. | ||
* parameters: | ||
* refType - A tag from ConstantPoolInfo, which has to be either FIELDREF, METHODREF, INTERFACEMETHODREF | ||
* nameIndex - The index into the constant pool that represents the class | ||
*/ | ||
function ConstantRefInfo(refType, classIndex, nameAndTypeIndex) { | ||
inherits(this,"ConstantPoolInfo", refType); | ||
this.classIndex = classIndex; | ||
this.nameAndTypeIndex = nameAndTypeIndex; | ||
//Lazily resolve; do not access directly. | ||
this._class = undefined; | ||
this._ref = undefined; | ||
|
||
//Resolve all references to other constant pool objects. | ||
this.resolveReferences = function(constantPool) { | ||
//Make sure the class has resolved its references first. | ||
CONSTANTPOOL[this.classIndex].resolveReferences(); | ||
this.className = CONSTANTPOOL.getClassInfo(this.classIndex); | ||
this.nameAndType = CONSTANTPOOL[this.nameAndTypeIndex]; | ||
assert(this.nameAndType.tag == ConstantPoolInfo.tags.NAMEANDTYPE); | ||
}; | ||
|
||
/** | ||
* Get the field/method/interface method object. | ||
*/ | ||
this.getRef = function() { | ||
if (this._ref != undefined) | ||
return this._ref; | ||
|
||
var _class = this.getClass(); | ||
var name = this.nameAndType.name; | ||
var descriptor = this.nameAndType.descriptor; | ||
|
||
switch(this.tag) { | ||
case ConstantPoolInfo.tags.FIELDREF: | ||
this._ref = _class.getField(name, descriptor); | ||
break; | ||
case ConstantPoolInfo.tags.METHODREF: | ||
case ConstantPoolInfo.tags.INTERFACEMETHODREF: | ||
//TODO: Verify that interfaces work in the same way! | ||
//e.g. I don't have to peer through the interfaces in getMethod. | ||
this._ref = _class.getMethod(name, descriptor); | ||
break; | ||
defualt: | ||
break; | ||
} | ||
|
||
return this._ref; | ||
}; | ||
|
||
/** | ||
* Get the class object representing the class that this reference is from. | ||
*/ | ||
this.getClass = function() { | ||
if (this._class != undefined) | ||
return this._class; | ||
|
||
//addTextToConsole("CPRef ClassIndex: " + this.classIndex); | ||
this._class = Class.getClass(this.className); | ||
|
||
return this._class; | ||
}; | ||
|
||
this.toString = function() { | ||
var output = ""; | ||
|
||
switch(this.tag) | ||
{ | ||
case ConstantPoolInfo.tags.FIELDREF: | ||
output += "fieldref "; | ||
break; | ||
case ConstantPoolInfo.tags.METHODREF: | ||
output += "methodref "; | ||
break; | ||
case ConstantPoolInfo.tags.INTERFACEMETHODREF: | ||
output += "interfacemethodref "; | ||
break; | ||
default: | ||
output += "unknownref "; | ||
break; | ||
} | ||
|
||
return output + this.className + " " + this.nameAndType.name + " " + this.nameAndType.descriptor; | ||
} | ||
|
||
this.print = function() { | ||
addTextToCurrentLine(this.toString()); | ||
}; | ||
} | ||
|
||
//Used for Strings | ||
function ConstantStringInfo(stringIndex) { | ||
inherits(this,"ConstantPoolInfo", ConstantPoolInfo.tags.STRING); | ||
this.stringIndex = stringIndex; | ||
|
||
//Resolve all references to other constant pool objects. | ||
this.resolveReferences = function(constantPool) { | ||
this.string = CONSTANTPOOL.getUTF8Info(this.stringIndex); | ||
}; | ||
|
||
this.print = function() { | ||
addTextToCurrentLine("string " + this.string); | ||
} | ||
} | ||
|
||
//Used for INTEGER OR FLOATING REFERENCES | ||
function ConstantNumberInfo(refType, value) { | ||
inherits(this,"ConstantPoolInfo", refType); | ||
this.value = value; | ||
|
||
this.print = function() { | ||
var output = ""; | ||
|
||
switch(this.tag) | ||
{ | ||
case ConstantPoolInfo.tags.INTEGER: | ||
output += "int "; | ||
break; | ||
case ConstantPoolInfo.tags.FLOAT: | ||
output += "float "; | ||
break; | ||
default: | ||
output += "unknownnumber "; | ||
break; | ||
} | ||
|
||
addTextToCurrentLine(output + this.value); | ||
}; | ||
} | ||
|
||
//Used for LONGS and DOUBLES | ||
function ConstantBigNumberInfo(refType, value) { | ||
inherits(this,"ConstantPoolInfo", refType); | ||
this.value = value; | ||
|
||
this.print = function() { | ||
var output = ""; | ||
switch(this.tag) | ||
{ | ||
case ConstantPoolInfo.tags.LONG: | ||
output += "long "; | ||
break; | ||
case ConstantPoolInfo.tags.DOUBLE: | ||
output += "double "; | ||
break; | ||
default: | ||
output += "unknownbignumber "; | ||
break; | ||
} | ||
|
||
addTextToCurrentLine(output + this.value); | ||
}; | ||
} | ||
|
||
function ConstantNameAndTypeInfo(nameIndex, descriptorIndex) { | ||
inherits(this,"ConstantPoolInfo", ConstantPoolInfo.tags.NAMEANDTYPE); | ||
this.nameIndex = nameIndex; | ||
this.descriptorIndex = descriptorIndex; | ||
|
||
//Resolve all references to other constant pool objects. | ||
this.resolveReferences = function(constantPool) { | ||
this.name = CONSTANTPOOL.getUTF8Info(this.nameIndex); | ||
|
||
this.descriptor = CONSTANTPOOL.getUTF8Info(this.descriptorIndex); | ||
}; | ||
|
||
this.print = function() { | ||
addTextToCurrentLine("NameAndTypeInfo" + this.name + " " + this.descriptor); | ||
}; | ||
} | ||
|
||
function ConstantUTF8Info(length, string) { | ||
inherits(this,"ConstantPoolInfo", ConstantPoolInfo.tags.UTF8); | ||
this.length = length; | ||
this.string = string; | ||
|
||
this.print = function() { | ||
addTextToCurrentLine("UTF8 " + this.string); | ||
}; | ||
} |
Oops, something went wrong.