1.1 --- a/javaclass/classfile.py Sun Sep 18 20:25:18 2011 +0100
1.2 +++ b/javaclass/classfile.py Sat Oct 08 19:11:03 2011 +0200
1.3 @@ -383,6 +383,7 @@
1.4 self.descriptor_index = u2(data[4:6])
1.5 self.attributes, data = self.class_file._get_attributes(data[6:])
1.6 return data
1.7 +
1.8 def serialize(self):
1.9 od = su2(self.access_flags)+su2(self.name_index)+su2(self.descriptor_index)
1.10 od += self.class_file._serialize_attributes(self.attributes)
1.11 @@ -401,6 +402,7 @@
1.12 self.attribute_length = u4(data[0:4])
1.13 self.info = data[4:4+self.attribute_length]
1.14 return data[4+self.attribute_length:]
1.15 +
1.16 def serialize(self):
1.17 return su4(self.attribute_length)+self.info
1.18
1.19 @@ -413,6 +415,7 @@
1.20 # Permit the NameUtils mix-in.
1.21 self.name_index = self.sourcefile_index = u2(data[4:6])
1.22 return data[6:]
1.23 +
1.24 def serialize(self):
1.25 return su4(self.attribute_length)+su2(self.name_index)
1.26
1.27 @@ -448,6 +451,7 @@
1.28 self.exception_table.append(exception)
1.29 self.attributes, data = self.class_file._get_attributes(data)
1.30 return data
1.31 +
1.32 def serialize(self):
1.33 od = su4(self.attribute_length)+su2(self.max_stack)+su2(self.max_locals)+su4(self.code_length)+self.code
1.34 od += su2(self.exception_table_length)
1.35 @@ -562,41 +566,56 @@
1.36 class VerificationTypeInfo(object):
1.37 def __init__(self, tag):
1.38 self.tag = tag
1.39 +
1.40 def init(self, data, class_file):
1.41 self.class_file = class_file
1.42 tag = u1(data[0:1])
1.43 assert(tag == self.tag)
1.44 return data[1:]
1.45 +
1.46 def serialize(self):
1.47 return su1(self.tag)
1.48 +
1.49 class TopVariableInfo(VerificationTypeInfo):
1.50 TAG = 0
1.51 +
1.52 class IntegerVariableInfo(VerificationTypeInfo):
1.53 TAG = 1
1.54 +
1.55 class FloatVariableInfo(VerificationTypeInfo):
1.56 TAG = 2
1.57 +
1.58 class DoubleVariableInfo(VerificationTypeInfo):
1.59 TAG = 3
1.60 +
1.61 class LongVariableInfo(VerificationTypeInfo):
1.62 TAG = 4
1.63 +
1.64 class NullVariableInfo(VerificationTypeInfo):
1.65 TAG = 5
1.66 +
1.67 class UninitializedThisVariableInfo(VerificationTypeInfo):
1.68 TAG = 6
1.69 +
1.70 class ObjectVariableInfo(VerificationTypeInfo):
1.71 TAG = 7
1.72 +
1.73 def init(self, data, class_file):
1.74 data = super(ObjectVariableInfo, self).init(data, class_file)
1.75 self.cpool_index = u2(data)
1.76 return data[2:]
1.77 +
1.78 def serialize(self):
1.79 return super(ObjectVariableInfo, self).serialize() + su2(self.cpool_index)
1.80 +
1.81 class UninitializedVariableInfo(VerificationTypeInfo):
1.82 TAG = 8
1.83 +
1.84 def init(self, data, class_file):
1.85 data = super(UninitializedVariableInfo, self).init(data, class_file)
1.86 self.offset = u2(data)
1.87 return data[2:]
1.88 +
1.89 def serialize(self):
1.90 return super(UninitializedVariableInfo, self).serialize() + su2(self.offset)
1.91
1.92 @@ -605,77 +624,95 @@
1.93 ObjectVariableInfo, UninitializedVariableInfo)
1.94 VARIABLE_INFO_TAG_MAP = dict([(cls.TAG, cls) for cls in VARIABLE_INFO_CLASSES])
1.95
1.96 -# Exception
1.97 +# Exception.
1.98 +
1.99 class UnknownVariableInfo:
1.100 def __init__(self, tag):
1.101 self.tag = tag
1.102 +
1.103 def __str__(self):
1.104 return repr(self.tag)
1.105
1.106 def create_verification_type_info(data):
1.107 - # Does not consume data, just does lookahead
1.108 + # Does not consume data, just does lookahead.
1.109 tag = u1(data[0:1])
1.110 if tag in VARIABLE_INFO_TAG_MAP:
1.111 return VARIABLE_INFO_TAG_MAP[tag](tag)
1.112 else:
1.113 raise UnknownVariableInfo, tag
1.114
1.115 -
1.116 class StackMapFrame(object):
1.117 def __init__(self, frame_type):
1.118 self.frame_type = frame_type
1.119 +
1.120 def init(self, data, class_file):
1.121 self.class_file = class_file
1.122 frame_type = u1(data[0:1])
1.123 assert(frame_type == self.frame_type)
1.124 return data[1:]
1.125 +
1.126 def serialize(self):
1.127 return su1(self.frame_type)
1.128 +
1.129 class SameFrame(StackMapFrame):
1.130 TYPE_LOWER = 0
1.131 TYPE_UPPER = 63
1.132 +
1.133 class SameLocals1StackItemFrame(StackMapFrame):
1.134 TYPE_LOWER = 64
1.135 TYPE_UPPER = 127
1.136 +
1.137 def init(self, data, class_file):
1.138 data = super(SameLocals1StackItemFrame, self).init(data, class_file)
1.139 self.offset_delta = self.frame_type - 64
1.140 self.stack = [create_verification_type_info(data)]
1.141 return self.stack[0].init(data, class_file)
1.142 +
1.143 def serialize(self):
1.144 return super(SameLocals1StackItemFrame, self).serialize()+self.stack[0].serialize()
1.145 +
1.146 class SameLocals1StackItemFrameExtended(StackMapFrame):
1.147 TYPE_LOWER = 247
1.148 TYPE_UPPER = 247
1.149 +
1.150 def init(self, data, class_file):
1.151 data = super(SameLocals1StackItemFrameExtended, self).init(data, class_file)
1.152 self.offset_delta = u2(data[0:2])
1.153 data = data[2:]
1.154 self.stack = [create_verification_type_info(data)]
1.155 return self.stack[0].init(data, class_file)
1.156 +
1.157 def serialize(self):
1.158 return super(SameLocals1StackItemFrameExtended, self).serialize()+su2(self.offset_delta)+self.stack[0].serialize()
1.159 +
1.160 class ChopFrame(StackMapFrame):
1.161 TYPE_LOWER = 248
1.162 TYPE_UPPER = 250
1.163 +
1.164 def init(self, data, class_file):
1.165 data = super(ChopFrame, self).init(data, class_file)
1.166 self.offset_delta = u2(data[0:2])
1.167 return data[2:]
1.168 +
1.169 def serialize(self):
1.170 return super(ChopFrame, self).serialize()+su2(self.offset_delta)
1.171 +
1.172 class SameFrameExtended(StackMapFrame):
1.173 TYPE_LOWER = 251
1.174 TYPE_UPPER = 251
1.175 +
1.176 def init(self, data, class_file):
1.177 data = super(SameFrameExtended, self).init(data, class_file)
1.178 self.offset_delta = u2(data[0:2])
1.179 return data[2:]
1.180 +
1.181 def serialize(self):
1.182 return super(SameFrameExtended, self).serialize()+su2(self.offset_delta)
1.183 +
1.184 class AppendFrame(StackMapFrame):
1.185 TYPE_LOWER = 252
1.186 TYPE_UPPER = 254
1.187 +
1.188 def init(self, data, class_file):
1.189 data = super(AppendFrame, self).init(data, class_file)
1.190 self.offset_delta = u2(data[0:2])
1.191 @@ -687,13 +724,16 @@
1.192 data = info.init(data, class_file)
1.193 self.locals.append(info)
1.194 return data
1.195 +
1.196 def serialize(self):
1.197 od = super(AppendFrame, self).serialize()+su2(self.offset_delta)
1.198 od += "".join([l.serialize() for l in self.locals])
1.199 return od
1.200 +
1.201 class FullFrame(StackMapFrame):
1.202 TYPE_LOWER = 255
1.203 TYPE_UPPER = 255
1.204 +
1.205 def init(self, data, class_file):
1.206 data = super(FullFrame, self).init(data, class_file)
1.207 self.offset_delta = u2(data[0:2])
1.208 @@ -712,6 +752,7 @@
1.209 data = stack_item.init(data, class_file)
1.210 self.stack.append(stack_item)
1.211 return data
1.212 +
1.213 def serialize(self):
1.214 od = super(FullFrame, self).serialize()+su2(self.offset_delta)+su2(len(self.locals))
1.215 od += "".join([l.serialize() for l in self.locals])
1.216 @@ -722,7 +763,8 @@
1.217 FRAME_CLASSES = (SameFrame, SameLocals1StackItemFrame, SameLocals1StackItemFrameExtended,
1.218 ChopFrame, SameFrameExtended, AppendFrame, FullFrame)
1.219
1.220 -# Exception
1.221 +# Exception.
1.222 +
1.223 class UnknownStackFrame:
1.224 def __init__(self, frame_type):
1.225 self.frame_type = frame_type
1.226 @@ -730,7 +772,7 @@
1.227 return repr(self.frame_type)
1.228
1.229 def create_stack_frame(data):
1.230 - # Does not consume data, just does lookahead
1.231 + # Does not consume data, just does lookahead.
1.232 frame_type = u1(data[0:1])
1.233 for cls in FRAME_CLASSES:
1.234 if frame_type >= cls.TYPE_LOWER and frame_type <= cls.TYPE_UPPER:
1.235 @@ -749,12 +791,12 @@
1.236 data = frame.init(data, class_file)
1.237 self.entries.append(frame)
1.238 return data
1.239 +
1.240 def serialize(self):
1.241 od = su4(self.attribute_length)+su2(len(self.entries))
1.242 od += "".join([e.serialize() for e in self.entries])
1.243 return od
1.244
1.245 -
1.246 class EnclosingMethodAttributeInfo(AttributeInfo):
1.247 def init(self, data, class_file):
1.248 self.class_file = class_file
1.249 @@ -762,69 +804,80 @@
1.250 self.class_index = u2(data[4:6])
1.251 self.method_index = u2(data[6:8])
1.252 return data[8:]
1.253 +
1.254 def serialize(self):
1.255 return su4(self.attribute_length)+su2(self.class_index)+su2(self.method_index)
1.256
1.257 -
1.258 class SignatureAttributeInfo(AttributeInfo):
1.259 def init(self, data, class_file):
1.260 self.class_file = class_file
1.261 self.attribute_length = u4(data[0:4])
1.262 self.signature_index = u2(data[4:6])
1.263 return data[6:]
1.264 +
1.265 def serialize(self):
1.266 return su4(self.attribute_length)+su2(self.signature_index)
1.267
1.268 -
1.269 class SourceDebugExtensionAttributeInfo(AttributeInfo):
1.270 def init(self, data, class_file):
1.271 self.class_file = class_file
1.272 self.attribute_length = u4(data[0:4])
1.273 self.debug_extension = data[4:(4 + self.attribute_length)]
1.274 return data[(4+ self.attribute_length):]
1.275 +
1.276 def serialize(self):
1.277 return su4(self.attribute_length)+self.debug_extension
1.278
1.279 -
1.280 class ElementValue(object):
1.281 def __init__(self, tag):
1.282 self.tag = tag
1.283 +
1.284 def init(self, data, class_file):
1.285 self.class_file = class_file
1.286 tag = chr(u1(data[0:1]))
1.287 assert(tag == self.tag)
1.288 return data[1:]
1.289 +
1.290 def serialize(self):
1.291 return su1(ord(self.tag))
1.292 +
1.293 class ConstValue(ElementValue):
1.294 def init(self, data, class_file):
1.295 data = super(ConstValue, self).init(data, class_file)
1.296 self.const_value_index = u2(data[0:2])
1.297 return data[2:]
1.298 +
1.299 def serialize(self):
1.300 return super(ConstValue, self).serialize()+su2(self.const_value_index)
1.301 +
1.302 class EnumConstValue(ElementValue):
1.303 def init(self, data, class_file):
1.304 data = super(EnumConstValue, self).init(data, class_file)
1.305 self.type_name_index = u2(data[0:2])
1.306 self.const_name_index = u2(data[2:4])
1.307 return data[4:]
1.308 +
1.309 def serialize(self):
1.310 return super(EnumConstValue, self).serialize()+su2(self.type_name_index)+su2(self.const_name_index)
1.311 +
1.312 class ClassInfoValue(ElementValue):
1.313 def init(self, data, class_file):
1.314 data = super(ClassInfoValue, self).init(data, class_file)
1.315 self.class_info_index = u2(data[0:2])
1.316 return data[2:]
1.317 +
1.318 def serialize(self):
1.319 return super(ClassInfoValue, self).serialize()+su2(self.class_info_index)
1.320 +
1.321 class AnnotationValue(ElementValue):
1.322 def init(self, data, class_file):
1.323 data = super(AnnotationValue, self).init(data, class_file)
1.324 self.annotation_value = Annotation()
1.325 return self.annotation_value.init(data, class_file)
1.326 +
1.327 def serialize(self):
1.328 return super(AnnotationValue, self).serialize()+self.annotation_value.serialize()
1.329 +
1.330 class ArrayValue(ElementValue):
1.331 def init(self, data, class_file):
1.332 data = super(ArrayValue, self).init(data, class_file)
1.333 @@ -836,11 +889,14 @@
1.334 data = element_value.init(data, class_file)
1.335 self.values.append(element_value)
1.336 return data
1.337 +
1.338 def serialize(self):
1.339 od = super(ArrayValue, self).serialize()+su2(len(self.values))
1.340 od += "".join([v.serialize() for v in self.values])
1.341 return od
1.342 -# Exception
1.343 +
1.344 +# Exception.
1.345 +
1.346 class UnknownElementValue:
1.347 def __init__(self, tag):
1.348 self.tag = tag
1.349 @@ -861,7 +917,6 @@
1.350 return ArrayValue(tag)
1.351 else:
1.352 raise UnknownElementValue, tag
1.353 -
1.354
1.355 class Annotation(object):
1.356 def init(self, data, class_file):
1.357 @@ -877,12 +932,12 @@
1.358 data = element_value.init(data, class_file)
1.359 self.element_value_pairs.append((element_name_index, element_value))
1.360 return data
1.361 +
1.362 def serialize(self):
1.363 od = su2(self.type_index)+su2(len(self.element_value_pairs))
1.364 od += "".join([su2(evp[0])+evp[1].serialize() for evp in self.element_value_pairs])
1.365 return od
1.366
1.367 -
1.368 class RuntimeAnnotationsAttributeInfo(AttributeInfo):
1.369 def init(self, data, class_file):
1.370 self.class_file = class_file
1.371 @@ -895,6 +950,7 @@
1.372 data = annotation.init(data, class_file)
1.373 self.annotations.append(annotation)
1.374 return data
1.375 +
1.376 def serialize(self):
1.377 od = su4(self.attribute_length)+su2(len(self.annotations))
1.378 od += "".join([a.serialize() for a in self.annotations])
1.379 @@ -923,6 +979,7 @@
1.380 annotations.append(annotation)
1.381 self.parameter_annotations.append(annotations)
1.382 return data
1.383 +
1.384 def serialize(self):
1.385 od = su4(self.attribute_length)+su1(len(self.parameter_annotations))
1.386 for pa in self.parameter_annotations:
1.387 @@ -943,10 +1000,10 @@
1.388 data = data[4:]
1.389 self.default_value = create_element_value(data)
1.390 return self.default_value.init(data, class_file)
1.391 +
1.392 def serialize(self):
1.393 return su4(self.attribute_length)+self.default_value.serialize()
1.394
1.395 -
1.396 # Child classes of the attribute information classes.
1.397
1.398 class ExceptionInfo:
1.399 @@ -956,6 +1013,7 @@
1.400 self.handler_pc = u2(data[4:6])
1.401 self.catch_type = u2(data[6:8])
1.402 return data[8:]
1.403 +
1.404 def serialize(self):
1.405 return su2(self.start_pc)+su2(self.end_pc)+su2(self.handler_pc)+su2(self.catch_type)
1.406
1.407 @@ -968,6 +1026,7 @@
1.408 self.name_index = self.inner_name_index = u2(data[4:6])
1.409 self.inner_class_access_flags = u2(data[6:8])
1.410 return data[8:]
1.411 +
1.412 def serialize(self):
1.413 return su2(self.inner_class_info_index)+su2(self.outer_class_info_index)+su2(self.name_index)+su2(self.inner_class_access_flags)
1.414