Last active
August 29, 2015 14:21
-
-
Save ahausmann/195077e98b35e5491620 to your computer and use it in GitHub Desktop.
Java Class file structure for Okteta, extended from example with field_info, method_info and attribute_info
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
var constantType = { | |
'Class': 7, | |
'Fieldref': 9, | |
'Methodref': 10, | |
'InterfaceMethodref': 11, | |
'String': 8, | |
'Integer': 3, | |
'Float': 4, | |
'Long': 5, | |
'Double': 6, | |
'NameAndType': 12, | |
'Utf8': 1, | |
'MethodHandle': 15, | |
'MethodType': 16, | |
'InvokeDynamic': 18 | |
}; | |
var classAccessFlags = { | |
'public': 0x0001, | |
'final': 0x0010, | |
'super': 0x0020, | |
'interface': 0x0200, | |
'abstract': 0x0400, | |
'synthetic': 0x1000, | |
'annotation': 0x2000, | |
'enum': 0x4000 | |
}; | |
/** represents an index into the constant pool array (actually just a uint16) */ | |
function cpIndex() { | |
function validateCpIndex(root) { | |
return this.value < root.constant_pool.length; | |
} | |
//TODO custom to string | |
var ret = uint16(); | |
ret.typeName = "cp_index"; | |
ret.validationFunc = validateCpIndex; | |
return ret; | |
} | |
/* create an object corresponding to the class file cp_info union */ | |
function cp_info() { | |
//the list of possible interpretations of this structure: | |
var cpAlternatives = [ | |
//this is the really verbose way of defining an alternative in the tagged union: | |
{ | |
structName: 'CONSTANT_Class_info', | |
selectIf: function(root) { | |
return this.tag.value == constantType.Class; | |
}, | |
fields: { | |
name_index: cpIndex() | |
} | |
}, | |
// we can also use a less verbose version using the predefined alternative() function | |
alternative(function(root) { return this.tag.value == constantType.String; }, //selectIf | |
{ name_index: cpIndex() }, //fields | |
'CONSTANT_String_info'), //structName | |
//it can be even shorter since there is only one value in this tagged union that can be used to decide | |
//therefore just passing the value as an argument is enough | |
alternative(constantType.Integer, { value : int32() }, 'CONSTANT_Integer_info'), | |
//obviously this also works if we define the object manually | |
{ | |
structName: 'CONSTANT_Float_info', | |
selectIf: constantType.Float, | |
fields: { value: float() } | |
}, | |
//just use the shortest syntax for the remaining alternatives | |
alternative(constantType.Long, { | |
value : int64() | |
}, 'CONSTANT_Long_info'), | |
alternative(constantType.Double, { | |
value : double() | |
}, 'CONSTANT_Double_info'), | |
alternative(constantType.Fieldref, { | |
class_index: cpIndex(), | |
name_and_type_index: cpIndex() | |
}, 'CONSTANT_Fieldref_info'), | |
alternative(constantType.Methodref, { | |
class_index: cpIndex(), | |
name_and_type_index: cpIndex() | |
}, 'CONSTANT_Methodref_info'), | |
alternative(constantType.InterfaceMethodref, { | |
class_index: cpIndex(), | |
name_and_type_index: cpIndex() | |
}, 'CONSTANT_InterfaceMethodref_info'), | |
alternative(constantType.NameAndType, { | |
name_index: cpIndex(), | |
descriptor_index: cpIndex() | |
}, 'CONSTANT_NameAndType_info'), | |
alternative(constantType.MethodHandle, { | |
reference_kind: uint8(), | |
reference_index: cpIndex() | |
}, 'CONSTANT_MethodHandle_info'), | |
alternative(constantType.MethodType, { | |
descriptor_index: cpIndex() | |
}, 'CONSTANT_MethodType_info'), | |
alternative(constantType.InvokeDynamic, { | |
bootstrap_method_attr_index: cpIndex(), | |
name_and_type_index: cpIndex() | |
}, 'CONSTANT_InvokeDynamic_info'), | |
alternative(constantType.Utf8, { | |
length: uint16(), | |
bytes: string('utf8').set({ | |
maxByteCount: 0, | |
updateFunc: function() { this.maxByteCount = this.parent.length.value; } | |
}) | |
}, 'CONSTANT_Utf8_info') | |
]; | |
/* first argument is the fixed elements, second is the alternatives, and last is the default fields (if none of the alternatives match) */ | |
return taggedUnion({ tag: enumeration('ConstantType', uint8(), constantType)}, cpAlternatives, { dummy: uint8() }); | |
} | |
function attribute_info() { | |
/* | |
attribute_info { | |
u2 name_index; | |
u4 length; | |
u1 info[length]; | |
} | |
*/ | |
var s = struct({ | |
name_index: cpIndex(), | |
length: uint32(), | |
info: array(uint8(), function(root) { return this.parent.length.value; }), | |
}); | |
s.typeName = "attribute_info"; | |
return s; | |
} | |
function field_info() { | |
/* | |
field_info { | |
u2 access_flags; | |
u2 name_index; | |
u2 descriptor_index; | |
u2 attributes_count; | |
attribute_info attributes[attributes_count]; | |
} | |
*/ | |
var s = struct({ | |
access_flags: access_flags(), | |
name_index: cpIndex(), | |
descriptor_index: cpIndex(), | |
attributes_count: uint16(), | |
attributes: array(attribute_info(), function(root) { return this.parent.attributes_count.value; }), | |
}); | |
s.typeName = "field_info"; | |
return s; | |
} | |
function method_info() { | |
/* | |
method_info { | |
u2 access_flags; | |
u2 name_index; | |
u2 descriptor_index; | |
u2 attributes_count; | |
attribute_info attributes[attributes_count]; | |
} | |
*/ | |
var s = struct({ | |
access_flags: access_flags(), | |
name_index: cpIndex(), | |
descriptor_index: cpIndex(), | |
attributes_count: uint16(), | |
attributes: array(attribute_info(), function(root) { return this.parent.attributes_count.value; }), | |
}); | |
s.typeName = "method_info"; | |
return s; | |
} | |
function access_flags() { | |
return flags('ClassAccessFlags', uint16(), classAccessFlags); | |
} | |
function init() { | |
//from http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html | |
/* | |
ClassFile { | |
u4 magic; | |
u2 minor_version; | |
u2 major_version; | |
u2 constant_pool_count; | |
cp_info constant_pool[constant_pool_count-1]; | |
u2 access_flags; | |
u2 this_class; | |
u2 super_class; | |
u2 interfaces_count; | |
u2 interfaces[interfaces_count]; | |
u2 fields_count; | |
field_info fields[fields_count]; | |
u2 methods_count; | |
method_info methods[methods_count]; | |
u2 attributes_count; | |
attribute_info attributes[attributes_count]; | |
} | |
*/ | |
var classFile = struct({ | |
magic: uint32(), | |
minor_version: uint16(), | |
major_version: uint16(), | |
constant_pool_count: uint16(), | |
/* length is always constant_pool_count - 1 */ | |
constant_pool: array(cp_info(), function(root) { return root.constant_pool_count.value - 1; }), | |
access_flags: flags('ClassAccessFlags', uint16(), classAccessFlags), | |
this_class: cpIndex(), | |
super_class: cpIndex(), | |
interfaces_count: uint16(), | |
interfaces: array(cpIndex(), function(root) { return root.interfaces_count.value; }), | |
fields_count: uint16(), | |
fields: array(field_info(), function(root) { return root.fields_count.value; }), | |
methods_count: uint16(), | |
methods: array(method_info(), function(root) { return root.methods_count.value; }), | |
attributes_count: uint16(), | |
attributes: array(attribute_info(), function(root) { return root.attributes_count.value; }), | |
}); | |
//classfile is always stored in big endian | |
classFile.byteOrder = "bigEndian"; | |
return classFile; | |
} |
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
[Desktop Entry] | |
Encoding=UTF-8 | |
Icon=application-x-java | |
Type=Service | |
ServiceTypes=KPluginInfo | |
Name=Java .class file format | |
Name[ca]=Format de fitxer .class del Java | |
Name[da]=Java .class-filformat | |
Name[de]=Java-„.class“-Dateiformat | |
Name[en_GB]=Java .class file format | |
Name[es]=Formato de archivo .class de Java | |
Name[fi]=Javan .class-tiedostomuoto | |
Name[fr]=Format de fichier « .class » Java | |
Name[gl]=Formato de ficheiro «.class» de Java | |
Name[hu]=Java .class fájlformátum | |
Name[it]=Formato di file .class di Java | |
Name[ko]=Java .class 파일 형식 | |
Name[nl]=Bestandsformaat van Java .class | |
Name[pl]=Format plików .class Javy | |
Name[pt]=Formato de ficheiro .class do Java | |
Name[pt_BR]=Formato de arquivo .class do Java | |
Name[ru]=Классы Java | |
Name[sk]=Formát súborov Java .class | |
Name[sr]=Формат јаванског .class фајла | |
Name[sr@ijekavian]=Формат јаванског .class фајла | |
Name[sr@ijekavianlatin]=Format javanskog .class fajla | |
Name[sr@latin]=Format javanskog .class fajla | |
Name[sv]=Java .class-filformat | |
Name[tr]=Java .class dosya biçimi | |
Name[uk]=Формат файлів .class Java | |
Name[x-test]=xxJava .class file formatxx | |
Name[zh_CN]=Java .class 文件格式 | |
Name[zh_TW]=Java .class 檔案格式 | |
Comment=still very incomplete!!! | |
Comment[ca]=Encara està molt incomplet! | |
Comment[da]=stadig langt fra færdigt!!! | |
Comment[de]=Noch sehr unvollständig | |
Comment[en_GB]=still very incomplete!!! | |
Comment[es]=Todavía bastante incompleto | |
Comment[fi]=vielä erittäin keskeneräinen! | |
Comment[fr]=Encore très incomplet !!! | |
Comment[gl]=Aínda está moi incompleto! | |
Comment[hu]=még mindig nagyon hiányos!!! | |
Comment[it]=Ancora molto incompleto! | |
Comment[ko]=여전히 불완전합니다!!! | |
Comment[nl]=nog steeds erg onvolledig!!! | |
Comment[pl]=nadal bardzo nieukończone!!! | |
Comment[pt]=ainda muito incompleto!!! | |
Comment[pt_BR]=ainda muito incompleto!!! | |
Comment[ru]=В процессе разработки | |
Comment[sk]=stále veľmi nekompletné!!! | |
Comment[sr]=Још увек врло непотпуно! | |
Comment[sr@ijekavian]=Још увек врло непотпуно! | |
Comment[sr@ijekavianlatin]=Još uvek vrlo nepotpuno! | |
Comment[sr@latin]=Još uvek vrlo nepotpuno! | |
Comment[sv]=Fortfarande mycket ofullständigt! | |
Comment[tr]=hala çok eksik!!! | |
Comment[uk]=Все ще доволі неповний! | |
Comment[x-test]=xxstill very incomplete!!!xx | |
Comment[zh_CN]=仍非常不完整!!! | |
Comment[zh_TW]=仍然不完整! | |
X-KDE-PluginInfo-Author=Alex Richardson & Alexander Hausmann | |
X-KDE-PluginInfo-Email=alex.richardson@gmx.de | |
X-KDE-PluginInfo-Name=classfile | |
X-KDE-PluginInfo-Version=0.2 | |
X-KDE-PluginInfo-Website=http://www.plugin.org/ | |
X-KDE-PluginInfo-Category=structure/js | |
X-KDE-PluginInfo-License=GPLv3 | |
X-KDE-PluginInfo-EnabledByDefault=false |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment