cleanup classinfo, resolve it earlier, don't keep classImage in memory

This commit is contained in:
Andreas Gal 2014-07-13 09:28:19 -07:00
Родитель 191585115e
Коммит 7401fda65d
4 изменённых файлов: 32 добавлений и 56 удалений

Просмотреть файл

@ -41,7 +41,7 @@ Classes.prototype.loadFile = function(fileName) {
Classes.prototype.loadClassBytes = function(bytes) {
var classInfo = new ClassInfo(bytes);
this.classes[classInfo.getClassName()] = classInfo;
this.classes[classInfo.className] = classInfo;
return classInfo;
}
@ -51,7 +51,7 @@ Classes.prototype.loadClassFile = function(fileName) {
if (!bytes)
return null;
var classInfo = this.loadClassBytes(bytes);
var classes = classInfo.getClasses();
var classes = classInfo.classes;
for (var i=0; i<classes.length; i++) {
if (!this.classes[classes[i]]) {
this.loadClassFile(path.dirname(fileName) + path.sep + classes[i] + ".class");
@ -64,10 +64,10 @@ Classes.prototype.getEntryPoint = function(className, methodName) {
for(var name in this.classes) {
var classInfo = this.classes[name];
if (classInfo instanceof ClassInfo) {
if (!className || (className === classInfo.getClassName())) {
if (ACCESS_FLAGS.isPublic(classInfo.getAccessFlags())) {
var methods = classInfo.getMethods();
var cp = classInfo.getConstantPool();
if (!className || (className === classInfo.className)) {
if (ACCESS_FLAGS.isPublic(classInfo.access_flags)) {
var methods = classInfo.methods;
var cp = classInfo.constant_pool;
for (var i=0; i<methods.length; i++) {
if (ACCESS_FLAGS.isPublic(methods[i].access_flags) &&
ACCESS_FLAGS.isStatic(methods[i].access_flags) &&
@ -116,8 +116,8 @@ Classes.prototype.getMethod = function(caller, className, methodName, signature,
console.log(className, methodName, signature);
// Only force initialization when accessing a static method.
var classInfo = this.getClass(caller, className, staticFlag);
var methods = classInfo.getMethods();
var cp = classInfo.getConstantPool();
var methods = classInfo.methods;
var cp = classInfo.constant_pool;
for (var i=0; i<methods.length; i++) {
if (ACCESS_FLAGS.isStatic(methods[i].access_flags) === !!staticFlag) {
if (cp[methods[i].name_index].bytes === methodName) {
@ -127,7 +127,7 @@ Classes.prototype.getMethod = function(caller, className, methodName, signature,
}
}
}
return inheritFlag ? this.getMethod(caller, classInfo.getSuperClassName(), methodName, signature, staticFlag, inheritFlag) : null;
return inheritFlag ? this.getMethod(caller, classInfo.superClassName, methodName, signature, staticFlag, inheritFlag) : null;
};
Classes.prototype.getStaticMethod = function(caller, className, methodName, signature) {

Просмотреть файл

@ -5,52 +5,28 @@
var ClassInfo = function(classBytes) {
if (this instanceof ClassInfo) {
this.classImage = getClassImage(classBytes, this);
var classImage = getClassImage(classBytes, this);
var cp = classImage.constant_pool;
this.className = cp[cp[classImage.this_class].name_index].bytes;
this.superClassName = classImage.super_class ? cp[cp[classImage.super_class].name_index].bytes : null;
this.access_flags = classImage.access_flags;
this.constant_pool = cp;
this.fields = classImage.fields;
this.methods = classImage.methods;
this.classes = [];
classImage.attributes.forEach(function(a) {
if (a.info.type === ATTRIBUTE_TYPES.InnerClasses) {
a.info.classes.forEach(function(c) {
classes.push(cp[cp[c.inner_class_info_index].name_index].bytes);
classes.push(cp[cp[c.outer_class_info_index].name_index].bytes);
});
}
});
} else {
return new ClassInfo(classBytes);
}
}
ClassInfo.prototype.getClassName = function() {
return this.classImage.constant_pool[this.classImage.constant_pool[this.classImage.this_class].name_index].bytes;
}
ClassInfo.prototype.getSuperClassName = function() {
if (!this.classImage.super_class)
return null;
return this.classImage.constant_pool[this.classImage.constant_pool[this.classImage.super_class].name_index].bytes;
}
ClassInfo.prototype.getAccessFlags = function() {
return this.classImage.access_flags;
}
ClassInfo.prototype.getConstantPool = function() {
return this.classImage.constant_pool;
}
ClassInfo.prototype.getFields = function() {
return this.classImage.fields;
}
ClassInfo.prototype.getMethods = function() {
return this.classImage.methods;
}
ClassInfo.prototype.getClasses = function() {
var self = this;
var classes = [];
this.classImage.attributes.forEach(function(a) {
if (a.info.type === ATTRIBUTE_TYPES.InnerClasses) {
a.info.classes.forEach(function(c) {
classes.push(self.classImage.constant_pool[self.classImage.constant_pool[c.inner_class_info_index].name_index].bytes);
classes.push(self.classImage.constant_pool[self.classImage.constant_pool[c.outer_class_info_index].name_index].bytes);
});
}
});
return classes;
}
var FieldInfo = function(classInfo, access_flags, name_index, descriptor_index) {
this.classInfo = classInfo;
this.access_flags = access_flags;

Просмотреть файл

@ -20,7 +20,7 @@ Array.prototype.top = function () {
var Frame = function(methodInfo) {
if (methodInfo) {
this.methodInfo = methodInfo;
this.cp = methodInfo.classInfo.getConstantPool();
this.cp = methodInfo.classInfo.constant_pool;
this.code = methodInfo.code;
this.ip = 0;
}
@ -76,7 +76,7 @@ Frame.prototype.throw = function(ex) {
handler_pc = this.exception_table[i].handler_pc;
} else {
var name = this.cp[this.cp[this.exception_table[i].catch_type].name_index].bytes;
if (name === ex.getClassName()) {
if (name === ex.className) {
handler_pc = this.exception_table[i].handler_pc;
break;
}
@ -137,7 +137,7 @@ Frame.prototype.invoke = function(methodInfo) {
while (true) {
var op = callee.read8();
console.log(callee.methodInfo.classInfo.getClassName(),
console.log(callee.methodInfo.classInfo.className,
callee.cp[callee.methodInfo.name_index].bytes,
callee.ip - 1, OPCODES[op], callee.stack.length);
switch (op) {
@ -1114,7 +1114,7 @@ Frame.prototype.instanceof = function() {
var idx = this.read16();
var className = this.cp[this.cp[idx].name_index].bytes;
var obj = this.stack.pop();
this.stack.push(obj.class.getClassName() === className);
this.stack.push(obj.class.className === className);
}
Frame.prototype.checkcast = function() {

Просмотреть файл

@ -42,8 +42,8 @@ Native.prototype.invokeNative = function(caller, methodInfo) {
Native.prototype.getMethod = function (methodInfo) {
var classInfo = methodInfo.classInfo;
var cp = classInfo.getConstantPool();
var className = classInfo.getClassName();
var cp = classInfo.constant_pool;
var className = classInfo.className;
var methodName = cp[methodInfo.name_index].bytes;
var signature = cp[methodInfo.signature_index].bytes;
console.log("Native.getMethod", className, methodName, signature);