1.1 --- a/bytecode.py Thu Oct 28 20:47:25 2004 +0200
1.2 +++ b/bytecode.py Fri Oct 29 18:48:35 2004 +0200
1.3 @@ -3,238 +3,783 @@
1.4 """
1.5 Java bytecode conversion. Specification found at the following URL:
1.6 http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc.html
1.7 +
1.8 +NOTE: Synchronized constructs are not actually supported.
1.9 """
1.10
1.11 import dis # for access to Python bytecode values
1.12
1.13 +# Bytecode production classes.
1.14 +
1.15 +class BytecodeWriter:
1.16 + def __init__(self):
1.17 + self.loops = []
1.18 + self.jumps = []
1.19 + self.output = []
1.20 + self.position = 0
1.21 +
1.22 + # Special methods.
1.23 +
1.24 + def end_loop(self):
1.25 + current_loop_start = self.loops.pop()
1.26 + self.jump_absolute(current_loop_start)
1.27 + self.output[current_loop_start + 1] = self.position
1.28 + self.pop_block()
1.29 +
1.30 + def jump_to_next(self, status):
1.31 + self.jumps.push(self.position)
1.32 + if status:
1.33 + self.jump_if_true()
1.34 + else:
1.35 + self.jump_if_false()
1.36 +
1.37 + def start_next(self):
1.38 + current_jump_start = self.jumps.pop()
1.39 + self.output[current_jump_start + 1] = self.position
1.40 +
1.41 + # Normal bytecode generators.
1.42 +
1.43 + def for_iter(self):
1.44 + self.loops.push(self.position)
1.45 + self.output.append(opmap["FOR_ITER"])
1.46 + self.output.append(None) # To be filled in later
1.47 + self.position += 2
1.48 +
1.49 + def jump_if_false(self, offset=None):
1.50 + self.output.append(opmap["JUMP_IF_FALSE"])
1.51 + self.output.append(offset) # May be filled in later
1.52 + self.position += 2
1.53 +
1.54 + def jump_if_true(self, offset=None):
1.55 + self.output.append(opmap["JUMP_IF_TRUE"])
1.56 + self.output.append(offset) # May be filled in later
1.57 + self.position += 2
1.58 +
1.59 # Bytecode conversion.
1.60
1.61 -def get_instructions(code):
1.62 - global java_bytecodes
1.63 +class BytecodeReader:
1.64 + def __init__(self, class_file):
1.65 + self.class_file = class_file
1.66 + self.position_mapping = {}
1.67 +
1.68 + def process(self, code, program):
1.69 + self.java_position = 0
1.70 + while self.java_position < len(code):
1.71 + self.position_mapping[self.java_position] = program.position
1.72 + bytecode = ord(code[self.java_position])
1.73 + mnemonic, number_of_arguments = self.java_bytecodes[bytecode]
1.74 + self.process_bytecode(mnemonic, number_of_arguments)
1.75 +
1.76 + def process_bytecode(self, mnemonic, number_of_arguments):
1.77 + if number_of_arguments is not None:
1.78 + arguments = []
1.79 + for j in range(0, number_of_arguments):
1.80 + arguments.append(ord(code[self.java_position + 1 + j]))
1.81 +
1.82 + # Call the handler.
1.83 + getattr(self, mnemonic)(arguments, program)
1.84 + else:
1.85 + # Call the handler.
1.86 + number_of_arguments = getattr(self, mnemonic)(code[self.java_position+1:], program)
1.87 +
1.88 + self.java_position = self.java_position + 1 + number_of_arguments
1.89 +
1.90 + def nop(self, arguments, program):
1.91 + pass
1.92 +
1.93 + def aaload(self, arguments, program):
1.94 + # NOTE: No type checking performed.
1.95 + program.binary_subscr()
1.96 +
1.97 + def aastore(self, arguments, program):
1.98 + # NOTE: No type checking performed.
1.99 + # Stack: arrayref, index, value
1.100 + program.rot_three() # Stack: value, arrayref, index
1.101 + program.store_subscr()
1.102 +
1.103 + def aconst_null(self, arguments, program):
1.104 + program.load_global(None)
1.105 +
1.106 + def aload(self, arguments, program):
1.107 + program.load_fast(arguments[0])
1.108 +
1.109 + def aload_0(self, arguments, program):
1.110 + program.load_fast(0)
1.111 +
1.112 + def aload_1(self, arguments, program):
1.113 + program.load_fast(1)
1.114 +
1.115 + def aload_2(self, arguments, program):
1.116 + program.load_fast(2)
1.117 +
1.118 + def aload_3(self, arguments, program):
1.119 + program.load_fast(3)
1.120 +
1.121 + def anewarray(self, arguments, program):
1.122 + # NOTE: Does not raise NegativeArraySizeException.
1.123 + # NOTE: Not using the index to type the list/array.
1.124 + index = arguments[0] << 8 + arguments[1]
1.125 +
1.126 + program.build_list()
1.127 + program.setup_loop()
1.128 + program.load_global("range")
1.129 + program.load_const(0) # Stack: list, count, range, 0
1.130 + program.rot_three() # Stack: list, 0, count, range
1.131 + program.rot_three() # Stack: list, range, 0, count
1.132 + program.call_function(2) # Stack: list, range_list
1.133 + program.get_iter() # Stack: list, iter
1.134 + program.for_iter() # Stack: list, iter, value
1.135 + program.pop_top() # Stack: list, iter
1.136 + program.rot_two() # Stack: iter, list
1.137 + program.dup_top() # Stack: iter, list, list
1.138 + program.load_attr("append") # Stack: iter, list, append
1.139 + program.load_global(None) # Stack: iter, list, append, None
1.140 + program.call_function(1) # Stack: iter, list, None
1.141 + program.pop_top() # Stack: iter, list
1.142 + program.rot_two() # Stack: list, iter
1.143 + program.end_loop() # Back to for_iter above
1.144 +
1.145 + def areturn(self, arguments, program):
1.146 + program.return_value()
1.147 +
1.148 + def arraylength(self, arguments, program):
1.149 + program.load_global("len") # Stack: arrayref, len
1.150 + program.rot_two() # Stack: len, arrayref
1.151 + program.call_function(1)
1.152
1.153 - i = 0
1.154 - instructions = []
1.155 - while i < len(code):
1.156 - bytecode = ord(code[i])
1.157 - mnemonic, number_of_arguments, stack_change = java_bytecodes[bytecode]
1.158 + def astore(self, arguments, program):
1.159 + program.store_fast(arguments[0])
1.160 +
1.161 + def astore_0(self, arguments, program):
1.162 + program.store_fast(0)
1.163 +
1.164 + def astore_1(self, arguments, program):
1.165 + program.store_fast(1)
1.166 +
1.167 + def astore_2(self, arguments, program):
1.168 + program.store_fast(2)
1.169 +
1.170 + def astore_3(self, arguments, program):
1.171 + program.store_fast(3)
1.172 +
1.173 + def athrow(self, arguments, program):
1.174 + # NOTE: NullPointerException not raised where null/None is found on the stack.
1.175 + program.raise_varargs(1)
1.176 +
1.177 + baload = aaload
1.178 + bastore = aastore
1.179 +
1.180 + def bipush(self, arguments, program):
1.181 + program.load_const(arguments[0])
1.182 +
1.183 + caload = aaload
1.184 + castore = aastore
1.185 +
1.186 + def checkcast(self, arguments, program):
1.187 + index = arguments[0] << 8 + arguments[1]
1.188 + target_name = self.class_file.constants[index - 1].get_name()
1.189 + target_components = target_name.split("/")
1.190 +
1.191 + program.dup_top() # Stack: objectref, objectref
1.192 + program.load_global("isinstance") # Stack: objectref, objectref, isinstance
1.193 + program.rot_two() # Stack: objectref, isinstance, objectref
1.194 + program.load_global(target_components[0])
1.195 + for target_component in target_components[1:]:
1.196 + program.load_attr(target_component)
1.197 + program.call_function(2) # Stack: objectref
1.198 +
1.199 + def d2f(self, arguments, program):
1.200 + pass
1.201 +
1.202 + def d2i(self, arguments, program):
1.203 + program.load_global("int") # Stack: value, int
1.204 + program.rot_two() # Stack: int, value
1.205 + program.call_function(1) # Stack: result
1.206 +
1.207 + d2l = d2i # Preserving Java semantics
1.208 +
1.209 + def dadd(self, arguments, program):
1.210 + # NOTE: No type checking performed.
1.211 + program.binary_add()
1.212 +
1.213 + daload = aaload
1.214 + dastore = aastore
1.215 +
1.216 + def dcmpg(self, arguments, program):
1.217 + # NOTE: No type checking performed.
1.218 + program.compare_op(">")
1.219 +
1.220 + def dcmpl(self, arguments, program):
1.221 + # NOTE: No type checking performed.
1.222 + program.compare_op("<")
1.223 +
1.224 + def dconst_0(self, arguments, program):
1.225 + program.load_const(0.0)
1.226 +
1.227 + def dconst_1(self, arguments, program):
1.228 + program.load_const(1.0)
1.229 +
1.230 + def ddiv(self, arguments, program):
1.231 + # NOTE: No type checking performed.
1.232 + program.binary_divide()
1.233 +
1.234 + dload = aload
1.235 + dload_0 = aload_0
1.236 + dload_1 = aload_1
1.237 + dload_2 = aload_2
1.238 + dload_3 = aload_3
1.239 +
1.240 + def dmul(self, arguments, program):
1.241 + # NOTE: No type checking performed.
1.242 + program.binary_multiply()
1.243 +
1.244 + def dneg(self, arguments, program):
1.245 + # NOTE: No type checking performed.
1.246 + program.unary_negative()
1.247
1.248 - # NOTE: To be fixed.
1.249 - if number_of_arguments is None:
1.250 - print "Stop at", mnemonic
1.251 - return instructions
1.252 + def drem(self, arguments, program):
1.253 + # NOTE: No type checking performed.
1.254 + program.binary_modulo()
1.255 +
1.256 + dreturn = areturn
1.257 + dstore = astore
1.258 + dstore_0 = astore_0
1.259 + dstore_1 = astore_1
1.260 + dstore_2 = astore_2
1.261 + dstore_3 = astore_3
1.262 +
1.263 + def dsub(self, arguments, program):
1.264 + # NOTE: No type checking performed.
1.265 + program.binary_subtract()
1.266 +
1.267 + def dup(self, arguments, program):
1.268 + program.dup_top()
1.269 +
1.270 + def dup_x1(self, arguments, program):
1.271 + # Ignoring computational type categories.
1.272 + program.dup_top()
1.273 + program.rot_three()
1.274 +
1.275 + def dup_x2(self, arguments, program):
1.276 + # Ignoring computational type categories.
1.277 + program.dup_top()
1.278 + program.rot_four()
1.279 +
1.280 + dup2 = dup # Ignoring computational type categories
1.281 + dup2_x1 = dup_x1 # Ignoring computational type categories
1.282 + dup2_x2 = dup_x2 # Ignoring computational type categories
1.283 +
1.284 + def f2d(self, arguments, program):
1.285 + pass # Preserving Java semantics
1.286 +
1.287 + def f2i(self, arguments, program):
1.288 + program.load_global("int") # Stack: value, int
1.289 + program.rot_two() # Stack: int, value
1.290 + program.call_function(1) # Stack: result
1.291 +
1.292 + f2l = f2i # Preserving Java semantics
1.293 + fadd = dadd
1.294 + faload = daload
1.295 + fastore = dastore
1.296 + fcmpg = dcmpg
1.297 + fcmpl = dcmpl
1.298 + fconst_0 = dconst_0
1.299 + fconst_1 = dconst_1
1.300 +
1.301 + def fconst_2(self, arguments, program):
1.302 + program.load_const(2.0)
1.303 +
1.304 + fdiv = ddiv
1.305 + fload = dload
1.306 + fload_0 = dload_0
1.307 + fload_1 = dload_1
1.308 + fload_2 = dload_2
1.309 + fload_3 = dload_3
1.310 + fmul = dmul
1.311 + fneg = dneg
1.312 + frem = drem
1.313 + freturn = dreturn
1.314 + fstore = dstore
1.315 + fstore_0 = dstore_0
1.316 + fstore_1 = dstore_1
1.317 + fstore_2 = dstore_2
1.318 + fstore_3 = dstore_3
1.319 + fsub = dsub
1.320 +
1.321 + def getfield(self, arguments, program):
1.322 + index = arguments[0] << 8 + arguments[1]
1.323 + target_name = self.class_file.constants[index - 1].get_name()
1.324 + # NOTE: Using the string version of the name which may contain incompatible characters.
1.325 + program.load_attr(str(target_name))
1.326 +
1.327 + getstatic = getfield # Ignoring Java restrictions
1.328 +
1.329 + def goto(self, arguments, program):
1.330 + offset = arguments[0] << 8 + arguments[1]
1.331 + java_absolute = self.java_position + offset
1.332 + program.jump_absolute(self.position_mapping[java_absolute])
1.333 +
1.334 + def goto_w(self, arguments, program):
1.335 + offset = arguments[0] << 24 + arguments[1] << 16 + arguments[2] << 8 + arguments[3]
1.336 + java_absolute = self.java_position + offset
1.337 + program.jump_absolute(self.position_mapping[java_absolute])
1.338 +
1.339 + def i2b(self, arguments, program):
1.340 + pass
1.341
1.342 - arguments = []
1.343 - for j in range(0, number_of_arguments):
1.344 - arguments.append(ord(code[i + 1 + j]))
1.345 + def i2c(self, arguments, program):
1.346 + program.load_global("chr") # Stack: value, chr
1.347 + program.rot_two() # Stack: chr, value
1.348 + program.call_function(1) # Stack: result
1.349 +
1.350 + def i2d(self, arguments, program):
1.351 + program.load_global("float") # Stack: value, float
1.352 + program.rot_two() # Stack: float, value
1.353 + program.call_function(1) # Stack: result
1.354 +
1.355 + i2f = i2d # Not distinguishing between float and double
1.356 +
1.357 + def i2l(self, arguments, program):
1.358 + pass # Preserving Java semantics
1.359 +
1.360 + def i2s(self, arguments, program):
1.361 + pass # Not distinguishing between int and short
1.362 +
1.363 + iadd = fadd
1.364 + iaload = faload
1.365 +
1.366 + def iand(self, arguments, program):
1.367 + # NOTE: No type checking performed.
1.368 + program.binary_and()
1.369 +
1.370 + iastore = fastore
1.371 +
1.372 + def iconst_m1(self, arguments, program):
1.373 + program.load_const(-1)
1.374 +
1.375 + def iconst_0(self, arguments, program):
1.376 + program.load_const(0)
1.377 +
1.378 + def iconst_1(self, arguments, program):
1.379 + program.load_const(1)
1.380 +
1.381 + def iconst_2(self, arguments, program):
1.382 + program.load_const(2)
1.383 +
1.384 + def iconst_3(self, arguments, program):
1.385 + program.load_const(3)
1.386 +
1.387 + def iconst_4(self, arguments, program):
1.388 + program.load_const(4)
1.389
1.390 - i = i + 1 + number_of_arguments
1.391 - instructions.append((mnemonic, arguments))
1.392 + def iconst_5(self, arguments, program):
1.393 + program.load_const(5)
1.394 +
1.395 + idiv = fdiv
1.396 +
1.397 + def _if_xcmpx(self, arguments, program, op):
1.398 + offset = arguments[0] << 8 + arguments[1]
1.399 + java_absolute = self.java_position + offset
1.400 + program.compare_op(op)
1.401 + program.jump_to_next(0) # skip if false
1.402 + program.goto(offset)
1.403 + program.start_next()
1.404 +
1.405 + def if_acmpeq(self, arguments, program):
1.406 + # NOTE: No type checking performed.
1.407 + self._if_xcmpx(arguments, program, "is")
1.408 +
1.409 + def if_acmpne(self, arguments, program):
1.410 + # NOTE: No type checking performed.
1.411 + self._if_xcmpx(arguments, program, "is not")
1.412
1.413 - return instructions
1.414 + def if_icmpeq(self, arguments, program):
1.415 + # NOTE: No type checking performed.
1.416 + self._if_xcmpx(arguments, program, "==")
1.417 +
1.418 + def if_icmpne(self, arguments, program):
1.419 + # NOTE: No type checking performed.
1.420 + self._if_xcmpx(arguments, program, "!=")
1.421 +
1.422 + def if_icmplt(self, arguments, program):
1.423 + # NOTE: No type checking performed.
1.424 + self._if_xcmpx(arguments, program, "<")
1.425 +
1.426 + def if_icmpge(self, arguments, program):
1.427 + # NOTE: No type checking performed.
1.428 + self._if_xcmpx(arguments, program, ">=")
1.429 +
1.430 + def if_icmpgt(self, arguments, program):
1.431 + # NOTE: No type checking performed.
1.432 + self._if_xcmpx(arguments, program, ">")
1.433 +
1.434 + def if_icmple(self, arguments, program):
1.435 + # NOTE: No type checking performed.
1.436 + self._if_xcmpx(arguments, program, "<=")
1.437
1.438 -java_bytecodes = {
1.439 - # code : (mnemonic, number of following bytes, change in stack)
1.440 - 0 : ("nop", 0, 0),
1.441 - 1 : ("aconst_null", 0, 1),
1.442 - 2 : ("iconst_m1", 0, 1),
1.443 - 3 : ("iconst_0", 0, 1),
1.444 - 4 : ("iconst_1", 0, 1),
1.445 - 5 : ("iconst_2", 0, 1),
1.446 - 6 : ("iconst_3", 0, 1),
1.447 - 7 : ("iconst_4", 0, 1),
1.448 - 8 : ("iconst_5", 0, 1),
1.449 - 9 : ("lconst_0", 0, 1),
1.450 - 10 : ("lconst_1", 0, 1),
1.451 - 11 : ("fconst_0", 0, 1),
1.452 - 12 : ("fconst_1", 0, 1),
1.453 - 13 : ("fconst_2", 0, 1),
1.454 - 14 : ("dconst_0", 0, 1),
1.455 - 15 : ("dconst_1", 0, 1),
1.456 - 16 : ("bipush", 1, 1),
1.457 - 17 : ("sipush", 2, 1),
1.458 - 18 : ("ldc", 1, 1),
1.459 - 19 : ("ldc_w", 2, 1),
1.460 - 20 : ("ldc2_w", 2, 1),
1.461 - 21 : ("iload", 1, 1),
1.462 - 22 : ("lload", 1, 1),
1.463 - 23 : ("fload", 1, 1),
1.464 - 24 : ("dload", 1, 1),
1.465 - 25 : ("aload", 1, 1),
1.466 - 26 : ("iload_0", 0, 1),
1.467 - 27 : ("iload_1", 0, 1),
1.468 - 28 : ("iload_2", 0, 1),
1.469 - 29 : ("iload_3", 0, 1),
1.470 - 30 : ("lload_0", 0, 1),
1.471 - 31 : ("lload_1", 0, 1),
1.472 - 32 : ("lload_2", 0, 1),
1.473 - 33 : ("lload_3", 0, 1),
1.474 - 34 : ("fload_0", 0, 1),
1.475 - 35 : ("fload_1", 0, 1),
1.476 - 36 : ("fload_2", 0, 1),
1.477 - 37 : ("fload_3", 0, 1),
1.478 - 38 : ("dload_0", 0, 1),
1.479 - 39 : ("dload_1", 0, 1),
1.480 - 40 : ("dload_2", 0, 1),
1.481 - 41 : ("dload_3", 0, 1),
1.482 - 42 : ("aload_0", 0, 1),
1.483 - 43 : ("aload_1", 0, 1),
1.484 - 44 : ("aload_2", 0, 1),
1.485 - 45 : ("aload_3", 0, 1),
1.486 - 46 : ("iaload", 0, -1),
1.487 - 47 : ("laload", 0, -1),
1.488 - 48 : ("faload", 0, -1),
1.489 - 49 : ("daload", 0, -1),
1.490 - 50 : ("aaload", 0, -1),
1.491 - 51 : ("baload", 0, -1),
1.492 - 52 : ("caload", 0, -1),
1.493 - 53 : ("saload", 0, -1),
1.494 - 54 : ("istore", 1, -1),
1.495 - 55 : ("lstore", 1, -1),
1.496 - 56 : ("fstore", 1, -1),
1.497 - 57 : ("dstore", 1, -1),
1.498 - 58 : ("astore", 1, -1),
1.499 - 59 : ("istore_0", 0, -1),
1.500 - 60 : ("istore_1", 0, -1),
1.501 - 61 : ("istore_2", 0, -1),
1.502 - 62 : ("istore_3", 0, -1),
1.503 - 63 : ("lstore_0", 0, -1),
1.504 - 64 : ("lstore_1", 0, -1),
1.505 - 65 : ("lstore_2", 0, -1),
1.506 - 66 : ("lstore_3", 0, -1),
1.507 - 67 : ("fstore_0", 0, -1),
1.508 - 68 : ("fstore_1", 0, -1),
1.509 - 69 : ("fstore_2", 0, -1),
1.510 - 70 : ("fstore_3", 0, -1),
1.511 - 71 : ("dstore_0", 0, -1),
1.512 - 72 : ("dstore_1", 0, -1),
1.513 - 73 : ("dstore_2", 0, -1),
1.514 - 74 : ("dstore_3", 0, -1),
1.515 - 75 : ("astore_0", 0, -1),
1.516 - 76 : ("astore_1", 0, -1),
1.517 - 77 : ("astore_2", 0, -1),
1.518 - 78 : ("astore_3", 0, -1),
1.519 - 79 : ("iastore", 0, -3),
1.520 - 80 : ("lastore", 0, -3),
1.521 - 81 : ("fastore", 0, -3),
1.522 - 82 : ("dastore", 0, -3),
1.523 - 83 : ("aastore", 0, -3),
1.524 - 84 : ("bastore", 0, -3),
1.525 - 85 : ("castore", 0, -3),
1.526 - 86 : ("sastore", 0, -3),
1.527 - 87 : ("pop", 0, -1),
1.528 - 88 : ("pop2", 0, None), # variable number of elements removed
1.529 - 89 : ("dup", 0, 1),
1.530 - 90 : ("dup_x1", 0, 1),
1.531 - 91 : ("dup_x2", 0, 1),
1.532 - 92 : ("dup2", 0, 2), # or 1 extra stack value
1.533 - 93 : ("dup2_x1", 0, 2), # or 1 extra stack value
1.534 - 94 : ("dup2_x2", 0, 2), # or 1 extra stack value
1.535 - 95 : ("swap", 0, 0),
1.536 - 96 : ("iadd", 0, -1),
1.537 - 97 : ("ladd", 0, -1),
1.538 - 98 : ("fadd", 0, -1),
1.539 - 99 : ("dadd", 0, -1),
1.540 - 100 : ("isub", 0, -1),
1.541 - 101 : ("lsub", 0, -1),
1.542 - 102 : ("fsub", 0, -1),
1.543 - 103 : ("dsub", 0, -1),
1.544 - 104 : ("imul", 0, -1),
1.545 - 105 : ("lmul", 0, -1),
1.546 - 106 : ("fmul", 0, -1),
1.547 - 107 : ("dmul", 0, -1),
1.548 - 108 : ("idiv", 0, -1),
1.549 - 109 : ("ldiv", 0, -1),
1.550 - 110 : ("fdiv", 0, -1),
1.551 - 111 : ("ddiv", 0, -1),
1.552 - 112 : ("irem", 0, -1),
1.553 - 113 : ("lrem", 0, -1),
1.554 - 114 : ("frem", 0, -1),
1.555 - 115 : ("drem", 0, -1),
1.556 - 116 : ("ineg", 0, 0),
1.557 - 117 : ("lneg", 0, 0),
1.558 - 118 : ("fneg", 0, 0),
1.559 - 119 : ("dneg", 0, 0),
1.560 - 120 : ("ishl", 0, -1),
1.561 - 121 : ("lshl", 0, -1),
1.562 - 122 : ("ishr", 0, -1),
1.563 - 123 : ("lshr", 0, -1),
1.564 - 124 : ("iushr", 0, -1),
1.565 - 125 : ("lushr", 0, -1),
1.566 - 126 : ("iand", 0, -1),
1.567 - 127 : ("land", 0, -1),
1.568 - 128 : ("ior", 0, -1),
1.569 - 129 : ("lor", 0, -1),
1.570 - 130 : ("ixor", 0, -1),
1.571 - 131 : ("lxor", 0, -1),
1.572 - 132 : ("iinc", 2, 0),
1.573 - 133 : ("i2l", 0, 0),
1.574 - 134 : ("i2f", 0, 0),
1.575 - 135 : ("i2d", 0, 0),
1.576 - 136 : ("l2i", 0, 0),
1.577 - 137 : ("l2f", 0, 0),
1.578 - 138 : ("l2d", 0, 0),
1.579 - 139 : ("f2i", 0, 0),
1.580 - 140 : ("f2l", 0, 0),
1.581 - 141 : ("f2d", 0, 0),
1.582 - 142 : ("d2i", 0, 0),
1.583 - 143 : ("d2l", 0, 0),
1.584 - 144 : ("d2f", 0, 0),
1.585 - 145 : ("i2b", 0, 0),
1.586 - 146 : ("i2c", 0, 0),
1.587 - 147 : ("i2s", 0, 0),
1.588 - 148 : ("lcmp", 0, -1),
1.589 - 149 : ("fcmpl", 0, -1),
1.590 - 150 : ("fcmpg", 0, -1),
1.591 - 151 : ("dcmpl", 0, -1),
1.592 - 152 : ("dcmpg", 0, -1),
1.593 - 153 : ("ifeq", 2, -1),
1.594 - 154 : ("ifne", 2, -1),
1.595 - 155 : ("iflt", 2, -1),
1.596 - 156 : ("ifge", 2, -1),
1.597 - 157 : ("ifgt", 2, -1),
1.598 - 158 : ("ifle", 2, -1),
1.599 - 159 : ("if_icmpeq", 2, -2),
1.600 - 160 : ("if_icmpne", 2, -2),
1.601 - 161 : ("if_icmplt", 2, -2),
1.602 - 162 : ("if_icmpge", 2, -2),
1.603 - 163 : ("if_icmpgt", 2, -2),
1.604 - 164 : ("if_icmple", 2, -2),
1.605 - 165 : ("if_acmpeq", 2, -2),
1.606 - 166 : ("if_acmpne", 2, -2),
1.607 - 167 : ("goto", 2, 0),
1.608 - 168 : ("jsr", 2, 1),
1.609 - 169 : ("ret", 1, 0),
1.610 - 170 : ("tableswitch", None, -1), # variable number of arguments
1.611 - 171 : ("lookupswitch", None, -1), # variable number of arguments
1.612 - 172 : ("ireturn", 0, -1),
1.613 - 173 : ("lreturn", 0, -1),
1.614 - 174 : ("freturn", 0, -1),
1.615 - 175 : ("dreturn", 0, -1),
1.616 - 176 : ("areturn", 0, -1),
1.617 - 177 : ("return", 0, 0),
1.618 - 178 : ("getstatic", 2, 1),
1.619 - 179 : ("putstatic", 2, -1),
1.620 - 180 : ("getfield", 2, 0),
1.621 - 181 : ("putfield", 2, -2),
1.622 - 182 : ("invokevirtual", 2, None), # variable number of elements removed
1.623 - 183 : ("invokespecial", 2, None), # variable number of elements removed
1.624 - 184 : ("invokestatic", 2, None), # variable number of elements removed
1.625 - 185 : ("invokeinterface", 4, None), # variable number of elements removed
1.626 - 187 : ("new", 2, 1),
1.627 - 188 : ("newarray", 1, 0),
1.628 - 189 : ("anewarray", 2, 0),
1.629 - 190 : ("arraylength", 0, 0),
1.630 - 191 : ("athrow", 0, 0),
1.631 - 192 : ("checkcast", 2, 0),
1.632 - 193 : ("instanceof", 2, 0),
1.633 - 194 : ("monitorenter", 0, -1),
1.634 - 195 : ("monitorexit", 0, -1),
1.635 - 196 : ("wide", None, None), # 3 or 5 arguments, stack changes according to modified element
1.636 - 197 : ("multianewarray", 3, None), # variable number of elements removed
1.637 - 198 : ("ifnull", 2, -1),
1.638 - 199 : ("ifnonnull", 2, -1),
1.639 - 200 : ("goto_w", 4, 0),
1.640 - 201 : ("jsr_w", 4, 1),
1.641 - }
1.642 + def ifeq(self, arguments, program):
1.643 + # NOTE: No type checking performed.
1.644 + program.load_const(0)
1.645 + self._if_xcmpx(arguments, program, "==")
1.646 +
1.647 + def ifne(self, arguments, program):
1.648 + # NOTE: No type checking performed.
1.649 + program.load_const(0)
1.650 + self._if_xcmpx(arguments, program, "!=")
1.651 +
1.652 + def iflt(self, arguments, program):
1.653 + # NOTE: No type checking performed.
1.654 + program.load_const(0)
1.655 + self._if_xcmpx(arguments, program, "<")
1.656 +
1.657 + def ifge(self, arguments, program):
1.658 + # NOTE: No type checking performed.
1.659 + program.load_const(0)
1.660 + self._if_xcmpx(arguments, program, ">=")
1.661 +
1.662 + def ifgt(self, arguments, program):
1.663 + # NOTE: No type checking performed.
1.664 + program.load_const(0)
1.665 + self._if_xcmpx(arguments, program, ">")
1.666 +
1.667 + def ifle(self, arguments, program):
1.668 + # NOTE: No type checking performed.
1.669 + program.load_const(0)
1.670 + self._if_xcmpx(arguments, program, "<=")
1.671 +
1.672 + def ifnonnull(self, arguments, program):
1.673 + # NOTE: No type checking performed.
1.674 + program.load_const(None)
1.675 + self._if_xcmpx(arguments, program, "is not")
1.676 +
1.677 + def ifnull(self, arguments, program):
1.678 + # NOTE: No type checking performed.
1.679 + program.load_const(None)
1.680 + self._if_xcmpx(arguments, program, "is")
1.681 +
1.682 + def iinc(self, arguments, program):
1.683 + # NOTE: No type checking performed.
1.684 + program.load_fast(arguments[0])
1.685 + program.load_const(arguments[1])
1.686 + program.binary_add()
1.687 +
1.688 + iload = fload
1.689 + iload_0 = fload_0
1.690 + iload_1 = fload_1
1.691 + iload_2 = fload_2
1.692 + iload_3 = fload_3
1.693 + imul = fmul
1.694 + ineg = fneg
1.695 +
1.696 + def instanceof(self, arguments, program):
1.697 + index = arguments[0] << 8 + arguments[1]
1.698 + target_name = self.class_file.constants[index - 1].get_name()
1.699 + target_components = target_name.split("/")
1.700 +
1.701 + program.load_global("isinstance") # Stack: objectref, isinstance
1.702 + program.rot_two() # Stack: isinstance, objectref
1.703 + program.load_global(target_components[0])
1.704 + for target_component in target_components[1:]:
1.705 + program.load_attr(target_component)
1.706 + program.call_function(2) # Stack: result
1.707 +
1.708 + def _invoke(self, target_name, program):
1.709 + program.rot_two() # Stack: tuple, objectref
1.710 + # NOTE: Using the string version of the name which may contain incompatible characters.
1.711 + program.load_attr(str(target_name)) # Stack: tuple, method
1.712 + program.rot_two() # Stack: method, tuple
1.713 + program.load_global("apply") # Stack: method, tuple, apply
1.714 + program.rot_three() # Stack: apply, method, tuple
1.715 + program.call_function(2)
1.716 +
1.717 + def invokeinterface(self, arguments, program):
1.718 + # NOTE: This implementation does not perform the necessary checks for
1.719 + # NOTE: signature-based polymorphism.
1.720 + # NOTE: Java rules not specifically obeyed.
1.721 + index = arguments[0] << 8 + arguments[1]
1.722 + count = arguments[2]
1.723 + target_name = self.class_file.constants[index - 1].get_name()
1.724 + # Stack: objectref, arg1, arg2, ...
1.725 + program.build_tuple(count) # Stack: objectref, tuple
1.726 + self._invoke(target_name, program)
1.727 +
1.728 + def invokespecial(self, arguments, program):
1.729 + # NOTE: This implementation does not perform the necessary checks for
1.730 + # NOTE: signature-based polymorphism.
1.731 + # NOTE: Java rules not specifically obeyed.
1.732 + index = arguments[0] << 8 + arguments[1]
1.733 + target = self.class_file.constants[index - 1]
1.734 + target_name = target.get_name()
1.735 + # Get the number of parameters from the descriptor.
1.736 + count = len(target.get_descriptor()[0])
1.737 + # Stack: objectref, arg1, arg2, ...
1.738 + program.build_tuple(count) # Stack: objectref, tuple
1.739 + self._invoke(target_name, program)
1.740 +
1.741 + def invokestatic(self, arguments, program):
1.742 + # NOTE: This implementation does not perform the necessary checks for
1.743 + # NOTE: signature-based polymorphism.
1.744 + # NOTE: Java rules not specifically obeyed.
1.745 + index = arguments[0] << 8 + arguments[1]
1.746 + target = self.class_file.constants[index - 1]
1.747 + target_name = target.get_name()
1.748 + # Get the number of parameters from the descriptor.
1.749 + count = len(target.get_descriptor()[0])
1.750 + # Stack: arg1, arg2, ...
1.751 + program.build_tuple(count) # Stack: tuple
1.752 + # NOTE: Should probably use Python static methods.
1.753 + program.load_name("self") # Stack: tuple, self
1.754 + self._invoke(target_name, program)
1.755 +
1.756 + invokevirtual = invokeinterface # Ignoring Java rules
1.757 +
1.758 + def ior(self, arguments, program):
1.759 + # NOTE: No type checking performed.
1.760 + program.binary_or()
1.761 +
1.762 + irem = frem
1.763 + ireturn = freturn
1.764 +
1.765 + def ishl(self, arguments, program):
1.766 + # NOTE: No type checking performed.
1.767 + # NOTE: Not verified.
1.768 + program.binary_lshift()
1.769 +
1.770 + def ishr(self, arguments, program):
1.771 + # NOTE: No type checking performed.
1.772 + # NOTE: Not verified.
1.773 + program.binary_rshift()
1.774 +
1.775 + istore = fstore
1.776 + istore_0 = fstore_0
1.777 + istore_1 = fstore_1
1.778 + istore_2 = fstore_2
1.779 + istore_3 = fstore_3
1.780 + isub = fsub
1.781 + iushr = ishr # Ignoring distinctions between arithmetic and logical shifts
1.782 +
1.783 + def ishr(self, arguments, program):
1.784 + # NOTE: No type checking performed.
1.785 + program.binary_xor()
1.786 +
1.787 + def jsr(self, arguments, program):
1.788 + offset = arguments[0] << 8 + arguments[1]
1.789 + java_absolute = self.java_position + offset
1.790 + # NOTE: To be implemented.
1.791 +
1.792 + def wide(self, code, program):
1.793 + # NOTE: To be implemented.
1.794 + return number_of_arguments
1.795 +
1.796 + java_bytecodes = {
1.797 + # code : (mnemonic, number of following bytes, change in stack)
1.798 + 0 : ("nop", 0),
1.799 + 1 : ("aconst_null", 0),
1.800 + 2 : ("iconst_m1", 0),
1.801 + 3 : ("iconst_0", 0),
1.802 + 4 : ("iconst_1", 0),
1.803 + 5 : ("iconst_2", 0),
1.804 + 6 : ("iconst_3", 0),
1.805 + 7 : ("iconst_4", 0),
1.806 + 8 : ("iconst_5", 0),
1.807 + 9 : ("lconst_0", 0),
1.808 + 10 : ("lconst_1", 0),
1.809 + 11 : ("fconst_0", 0),
1.810 + 12 : ("fconst_1", 0),
1.811 + 13 : ("fconst_2", 0),
1.812 + 14 : ("dconst_0", 0),
1.813 + 15 : ("dconst_1", 0),
1.814 + 16 : ("bipush", 1),
1.815 + 17 : ("sipush", 2),
1.816 + 18 : ("ldc", 1),
1.817 + 19 : ("ldc_w", 2),
1.818 + 20 : ("ldc2_w", 2),
1.819 + 21 : ("iload", 1),
1.820 + 22 : ("lload", 1),
1.821 + 23 : ("fload", 1),
1.822 + 24 : ("dload", 1),
1.823 + 25 : ("aload", 1),
1.824 + 26 : ("iload_0", 0),
1.825 + 27 : ("iload_1", 0),
1.826 + 28 : ("iload_2", 0),
1.827 + 29 : ("iload_3", 0),
1.828 + 30 : ("lload_0", 0),
1.829 + 31 : ("lload_1", 0),
1.830 + 32 : ("lload_2", 0),
1.831 + 33 : ("lload_3", 0),
1.832 + 34 : ("fload_0", 0),
1.833 + 35 : ("fload_1", 0),
1.834 + 36 : ("fload_2", 0),
1.835 + 37 : ("fload_3", 0),
1.836 + 38 : ("dload_0", 0),
1.837 + 39 : ("dload_1", 0),
1.838 + 40 : ("dload_2", 0),
1.839 + 41 : ("dload_3", 0),
1.840 + 42 : ("aload_0", 0),
1.841 + 43 : ("aload_1", 0),
1.842 + 44 : ("aload_2", 0),
1.843 + 45 : ("aload_3", 0),
1.844 + 46 : ("iaload", 0),
1.845 + 47 : ("laload", 0),
1.846 + 48 : ("faload", 0),
1.847 + 49 : ("daload", 0),
1.848 + 50 : ("aaload", 0),
1.849 + 51 : ("baload", 0),
1.850 + 52 : ("caload", 0),
1.851 + 53 : ("saload", 0),
1.852 + 54 : ("istore", 1),
1.853 + 55 : ("lstore", 1),
1.854 + 56 : ("fstore", 1),
1.855 + 57 : ("dstore", 1),
1.856 + 58 : ("astore", 1),
1.857 + 59 : ("istore_0", 0),
1.858 + 60 : ("istore_1", 0),
1.859 + 61 : ("istore_2", 0),
1.860 + 62 : ("istore_3", 0),
1.861 + 63 : ("lstore_0", 0),
1.862 + 64 : ("lstore_1", 0),
1.863 + 65 : ("lstore_2", 0),
1.864 + 66 : ("lstore_3", 0),
1.865 + 67 : ("fstore_0", 0),
1.866 + 68 : ("fstore_1", 0),
1.867 + 69 : ("fstore_2", 0),
1.868 + 70 : ("fstore_3", 0),
1.869 + 71 : ("dstore_0", 0),
1.870 + 72 : ("dstore_1", 0),
1.871 + 73 : ("dstore_2", 0),
1.872 + 74 : ("dstore_3", 0),
1.873 + 75 : ("astore_0", 0),
1.874 + 76 : ("astore_1", 0),
1.875 + 77 : ("astore_2", 0),
1.876 + 78 : ("astore_3", 0),
1.877 + 79 : ("iastore", 0),
1.878 + 80 : ("lastore", 0),
1.879 + 81 : ("fastore", 0),
1.880 + 82 : ("dastore", 0),
1.881 + 83 : ("aastore", 0),
1.882 + 84 : ("bastore", 0),
1.883 + 85 : ("castore", 0),
1.884 + 86 : ("sastore", 0),
1.885 + 87 : ("pop", 0),
1.886 + 88 : ("pop2", 0),
1.887 + 89 : ("dup", 0),
1.888 + 90 : ("dup_x1", 0),
1.889 + 91 : ("dup_x2", 0),
1.890 + 92 : ("dup2", 0),
1.891 + 93 : ("dup2_x1", 0),
1.892 + 94 : ("dup2_x2", 0),
1.893 + 95 : ("swap", 0),
1.894 + 96 : ("iadd", 0),
1.895 + 97 : ("ladd", 0),
1.896 + 98 : ("fadd", 0),
1.897 + 99 : ("dadd", 0),
1.898 + 100 : ("isub", 0),
1.899 + 101 : ("lsub", 0),
1.900 + 102 : ("fsub", 0),
1.901 + 103 : ("dsub", 0),
1.902 + 104 : ("imul", 0),
1.903 + 105 : ("lmul", 0),
1.904 + 106 : ("fmul", 0),
1.905 + 107 : ("dmul", 0),
1.906 + 108 : ("idiv", 0),
1.907 + 109 : ("ldiv", 0),
1.908 + 110 : ("fdiv", 0),
1.909 + 111 : ("ddiv", 0),
1.910 + 112 : ("irem", 0),
1.911 + 113 : ("lrem", 0),
1.912 + 114 : ("frem", 0),
1.913 + 115 : ("drem", 0),
1.914 + 116 : ("ineg", 0),
1.915 + 117 : ("lneg", 0),
1.916 + 118 : ("fneg", 0),
1.917 + 119 : ("dneg", 0),
1.918 + 120 : ("ishl", 0),
1.919 + 121 : ("lshl", 0),
1.920 + 122 : ("ishr", 0),
1.921 + 123 : ("lshr", 0),
1.922 + 124 : ("iushr", 0),
1.923 + 125 : ("lushr", 0),
1.924 + 126 : ("iand", 0),
1.925 + 127 : ("land", 0),
1.926 + 128 : ("ior", 0),
1.927 + 129 : ("lor", 0),
1.928 + 130 : ("ixor", 0),
1.929 + 131 : ("lxor", 0),
1.930 + 132 : ("iinc", 2),
1.931 + 133 : ("i2l", 0),
1.932 + 134 : ("i2f", 0),
1.933 + 135 : ("i2d", 0),
1.934 + 136 : ("l2i", 0),
1.935 + 137 : ("l2f", 0),
1.936 + 138 : ("l2d", 0),
1.937 + 139 : ("f2i", 0),
1.938 + 140 : ("f2l", 0),
1.939 + 141 : ("f2d", 0),
1.940 + 142 : ("d2i", 0),
1.941 + 143 : ("d2l", 0),
1.942 + 144 : ("d2f", 0),
1.943 + 145 : ("i2b", 0),
1.944 + 146 : ("i2c", 0),
1.945 + 147 : ("i2s", 0),
1.946 + 148 : ("lcmp", 0),
1.947 + 149 : ("fcmpl", 0),
1.948 + 150 : ("fcmpg", 0),
1.949 + 151 : ("dcmpl", 0),
1.950 + 152 : ("dcmpg", 0),
1.951 + 153 : ("ifeq", 2),
1.952 + 154 : ("ifne", 2),
1.953 + 155 : ("iflt", 2),
1.954 + 156 : ("ifge", 2),
1.955 + 157 : ("ifgt", 2),
1.956 + 158 : ("ifle", 2),
1.957 + 159 : ("if_icmpeq", 2),
1.958 + 160 : ("if_icmpne", 2),
1.959 + 161 : ("if_icmplt", 2),
1.960 + 162 : ("if_icmpge", 2),
1.961 + 163 : ("if_icmpgt", 2),
1.962 + 164 : ("if_icmple", 2),
1.963 + 165 : ("if_acmpeq", 2),
1.964 + 166 : ("if_acmpne", 2),
1.965 + 167 : ("goto", 2),
1.966 + 168 : ("jsr", 2),
1.967 + 169 : ("ret", 1),
1.968 + 170 : ("tableswitch", None), # variable number of arguments
1.969 + 171 : ("lookupswitch", None), # variable number of arguments
1.970 + 172 : ("ireturn", 0),
1.971 + 173 : ("lreturn", 0),
1.972 + 174 : ("freturn", 0),
1.973 + 175 : ("dreturn", 0),
1.974 + 176 : ("areturn", 0),
1.975 + 177 : ("return", 0),
1.976 + 178 : ("getstatic", 2),
1.977 + 179 : ("putstatic", 2),
1.978 + 180 : ("getfield", 2),
1.979 + 181 : ("putfield", 2),
1.980 + 182 : ("invokevirtual", 2),
1.981 + 183 : ("invokespecial", 2),
1.982 + 184 : ("invokestatic", 2),
1.983 + 185 : ("invokeinterface", 4),
1.984 + 187 : ("new", 2),
1.985 + 188 : ("newarray", 1),
1.986 + 189 : ("anewarray", 2),
1.987 + 190 : ("arraylength", 0),
1.988 + 191 : ("athrow", 0),
1.989 + 192 : ("checkcast", 2),
1.990 + 193 : ("instanceof", 2),
1.991 + 194 : ("monitorenter", 0),
1.992 + 195 : ("monitorexit", 0),
1.993 + 196 : ("wide", None), # 3 or 5 arguments, stack changes according to modified element
1.994 + 197 : ("multianewarray", 3),
1.995 + 198 : ("ifnull", 2),
1.996 + 199 : ("ifnonnull", 2),
1.997 + 200 : ("goto_w", 4),
1.998 + 201 : ("jsr_w", 4),
1.999 + }
1.1000 +
1.1001 +if __name__ == "__main__":
1.1002 + import sys
1.1003 + from classfile import ClassFile
1.1004 + f = open(sys.argv[1])
1.1005 + c = ClassFile(f.read())
1.1006
1.1007 # vim: tabstop=4 expandtab shiftwidth=4