2014-07-13 20:12:57 +04:00
|
|
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var ClassInfo = function(classBytes) {
|
2014-07-14 02:32:58 +04:00
|
|
|
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;
|
2014-07-13 21:37:28 +04:00
|
|
|
|
2014-07-14 02:32:58 +04:00
|
|
|
var self = this;
|
2014-07-13 21:37:28 +04:00
|
|
|
|
2014-07-18 10:26:34 +04:00
|
|
|
this.interfaces = [];
|
|
|
|
classImage.interfaces.forEach(function(i) {
|
|
|
|
self.interfaces.push(cp[cp[i].name_index].bytes);
|
|
|
|
});
|
|
|
|
|
2014-07-14 02:32:58 +04:00
|
|
|
this.fields = [];
|
|
|
|
classImage.fields.forEach(function(f) {
|
|
|
|
self.fields.push({
|
|
|
|
access_flags: f.access_flags,
|
|
|
|
name: cp[f.name_index].bytes,
|
|
|
|
descriptor: cp[f.descriptor_index].bytes,
|
|
|
|
attributes: f.attributes
|
2014-07-13 20:52:01 +04:00
|
|
|
});
|
2014-07-14 02:32:58 +04:00
|
|
|
});
|
2014-07-13 21:37:28 +04:00
|
|
|
|
2014-07-14 02:32:58 +04:00
|
|
|
this.methods = [];
|
|
|
|
classImage.methods.forEach(function(m) {
|
2014-07-14 06:58:30 +04:00
|
|
|
var method = {};
|
2014-07-14 02:32:58 +04:00
|
|
|
method.classInfo = self;
|
|
|
|
method.access_flags = m.access_flags;
|
|
|
|
method.name = cp[m.name_index].bytes;
|
|
|
|
method.signature = cp[m.signature_index].bytes;
|
|
|
|
method.attributes = m.attributes;
|
|
|
|
method.attributes.forEach(function(a) {
|
|
|
|
if (a.info.type === ATTRIBUTE_TYPES.Code) {
|
|
|
|
method.code = Uint8Array(a.info.code);
|
|
|
|
method.exception_table = a.info.exception_table;
|
|
|
|
method.max_locals = a.info.max_locals;
|
2014-07-13 20:28:19 +04:00
|
|
|
}
|
|
|
|
});
|
2014-07-14 02:32:58 +04:00
|
|
|
self.methods.push(method);
|
|
|
|
});
|
|
|
|
|
2014-07-16 03:49:00 +04:00
|
|
|
var classes = this.classes = [];
|
2014-07-14 02:32:58 +04:00
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2014-07-13 20:12:57 +04:00
|
|
|
}
|
2014-07-14 04:02:57 +04:00
|
|
|
|
2014-07-18 10:44:06 +04:00
|
|
|
ClassInfo.prototype.implementsInterface = function(iface) {
|
2014-07-18 10:02:28 +04:00
|
|
|
var classInfo = this;
|
|
|
|
do {
|
2014-07-18 10:44:06 +04:00
|
|
|
var interfaces = classInfo.interfaces;
|
|
|
|
for (var n = 0; n < interfaces.length; ++n) {
|
|
|
|
if (interfaces[n] === iface)
|
|
|
|
return true;
|
|
|
|
}
|
2014-07-18 10:02:28 +04:00
|
|
|
classInfo = classInfo.superClass;
|
|
|
|
} while (classInfo);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-18 10:44:06 +04:00
|
|
|
ClassInfo.prototype.canAssignTo = function(toClass) {
|
|
|
|
if (toClass.className === "java/lang/Object")
|
|
|
|
return true;
|
|
|
|
var fromClass = this;
|
|
|
|
do {
|
|
|
|
if (fromClass === toClass)
|
|
|
|
return true;
|
|
|
|
fromClass = classInfo.superClass;
|
|
|
|
} while (fromClass);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-18 10:02:28 +04:00
|
|
|
ClassInfo.prototype.getClassObject = function() {
|
|
|
|
var self = this;
|
|
|
|
return util.cache(this, "classObject", function () {
|
|
|
|
var classObject = CLASSES.newObject("java/lang/Class");
|
|
|
|
classObject.vmClass = self;
|
|
|
|
return classObject;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-07-14 04:02:57 +04:00
|
|
|
var ArrayClass = function(elementType) {
|
|
|
|
this.className = "[" + elementType;
|
|
|
|
this.superClassName = "java/lang/Object";
|
|
|
|
this.access_flags = 0;
|
|
|
|
this.elementType = elementType;
|
|
|
|
}
|
2014-07-18 10:11:45 +04:00
|
|
|
|
|
|
|
ArrayClass.prototype.isArrayClass = true;
|