def putfield(frame): index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 cp_fieldref = frame.this_class.constant_pool[index] assert cp_fieldref[0] == 9 # CONSTANT_Fieldref klass_info = frame.this_class.constant_pool[cp_fieldref[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_fieldref[2]] assert name_and_type[0] == 12 # CONSTANT_NameAndType_info klass_name = frame.this_class.constant_pool[klass_info[1]][1] field_name = frame.this_class.constant_pool[name_and_type[1]][1] logger.debug("putfield %s %s", field_name, klass_name) klass = frame.vm.get_class(klass_name) assert klass is not None value = frame.stack.pop() ref = frame.stack.pop() if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) if ref[0] == "vm_ref": raise Exception("Special handling required, see vmo.txt") instance = frame.vm.heap[ref[1]] assert field_name in instance.fields instance.fields[field_name] = value
def getfield(frame): index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 cp_fieldref = frame.this_class.constant_pool[index] assert cp_fieldref[0] == 9 # CONSTANT_Fieldref klass_info = frame.this_class.constant_pool[cp_fieldref[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_fieldref[2]] assert name_and_type[0] == 12 # CONSTANT_NameAndType_info klass_name = frame.this_class.constant_pool[klass_info[1]][1] field_name = frame.this_class.constant_pool[name_and_type[1]][1] logger.debug("getfield %s %s", klass_name, field_name) klass = frame.vm.get_class(klass_name) # At some point make sure object has right class assert klass is not None ref = frame.stack.pop() if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) if ref[0] == "vm_ref": raise Exception("Special handling required, see vmo.txt") instance = frame.vm.heap[ref[1]] assert field_name in instance.fields frame.stack.append(instance.fields[field_name])
def op_0xb4(frame): # getfield (from an obj) index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 cp_fieldref = frame.this_class.constant_pool[index] assert cp_fieldref[0] == 9 # CONSTANT_Fieldref klass_info = frame.this_class.constant_pool[cp_fieldref[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_fieldref[2]] assert name_and_type[0] == 12 # CONSTANT_NameAndType_info klass_name = frame.this_class.constant_pool[klass_info[1]][1] field_name = frame.this_class.constant_pool[name_and_type[1]][1] logger.debug("getfield %s %s", klass_name, field_name) klass = frame.vm.get_class(klass_name) # At some point make sure object has right class assert klass is not None ref = frame.stack.pop() if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) if ref[0] == "vm_ref": raise Exception("Special handling required, see vmo.txt") instance = frame.vm.heap[ref[1]] assert field_name in instance.fields frame.stack.append(instance.fields[field_name])
def op_0xc7(frame): # ifnonnull byte1 = ord(frame.code[frame.pc]) byte2 = ord(frame.code[frame.pc + 1]) frame.pc += 2 offset = struct.unpack(">h", chr(byte1) + chr(byte2))[0] value = frame.stack.pop() jassert_ref(value) if value is not None: frame.pc += offset - 2 - 1
def ifnonnull(frame): byte1 = ord(frame.code[frame.pc]) byte2 = ord(frame.code[frame.pc + 1]) frame.pc += 2 offset = struct.unpack(">h", chr(byte1) + chr(byte2))[0] value = frame.stack.pop() jassert_ref(value) if value is not None: frame.pc += offset - 2 - 1
def op_0xc3(frame): # monitorexit ref = frame.stack.pop() jassert_ref(ref) o = frame.vm.heap[ref[1]] if o.fields["@monitor_count"] == 1: del o.fields["@monitor"] del o.fields["@monitor_count"] else: o.fields["@monitor_count"] -= 1
def monitorexit(frame): ref = frame.stack.pop() jassert_ref(ref) o = frame.vm.heap[ref[1]] if o.fields["@monitor_count"] == 1: del o.fields["@monitor"] del o.fields["@monitor_count"] else: o.fields["@monitor_count"] -= 1
def athrow(frame): ref = frame.stack.pop() if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) frame.stack[:] = [] # empty stack frame.stack.append(ref) je = JavaException(frame.vm, ref) raise je
def op_0xa6(frame): # if_acmpne byte1 = ord(frame.code[frame.pc]) byte2 = ord(frame.code[frame.pc + 1]) frame.pc += 2 offset = struct.unpack(">h", chr(byte1) + chr(byte2))[0] value2 = frame.stack.pop() value1 = frame.stack.pop() jassert_ref(value1) jassert_ref(value2) if value1 != value2: frame.pc += offset - 2 - 1
def if_acmpne(frame): byte1 = ord(frame.code[frame.pc]) byte2 = ord(frame.code[frame.pc + 1]) frame.pc += 2 offset = struct.unpack(">h", chr(byte1) + chr(byte2))[0] value2 = frame.stack.pop() value1 = frame.stack.pop() jassert_ref(value1) jassert_ref(value2) if value1 != value2: frame.pc += offset - 2 - 1
def op_0xc2(frame): # monitorenter ref = frame.stack.pop() jassert_ref(ref) o = frame.vm.heap[ref[1]] if "@monitor" in o.fields: if o.fields["@monitor"] == frame.thread: o.fields["@monitor_count"] += 1 else: frame.stack.append(ref) raise SkipThreadCycle() else: o.fields["@monitor"] = frame.thread o.fields["@monitor_count"] = 1
def monitorenter(frame): ref = frame.stack.pop() jassert_ref(ref) o = frame.vm.heap[ref[1]] if "@monitor" in o.fields: if o.fields["@monitor"] == frame.thread: o.fields["@monitor_count"] += 1 else: frame.stack.append(ref) raise SkipThreadCycle() else: o.fields["@monitor"] = frame.thread o.fields["@monitor_count"] = 1
def aaload(frame): index = frame.stack.pop() ref = frame.stack.pop() jassert_int(index) if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) array = frame.vm.heap[ref[1]] values = array.values if index < 0 or index >= len(values): frame.vm.raise_exception(frame, "java/lang/ArrayIndexOutOfBoundsException") return frame.stack.append(values[index])
def sastore(frame): value = frame.stack.pop() index = frame.stack.pop() ref = frame.stack.pop() jassert_int(value) jassert_int(index) if ref is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return jassert_ref(ref) array = frame.vm.heap[ref[1]] jassert_array(array) values = array.values if index < 0 or index >= len(values): frame.vm.raise_exception(frame, "java/lang/ArrayIndexOutOfBoundsException") return values[index] = value
def op_0x2b(frame): # aload_1 value = frame.args[1] jassert_ref(value) frame.stack.append(value)
def op_0x2a(frame): # aload_0 value = frame.args[0] jassert_ref(value) frame.stack.append(value)
def op_0x19(frame): # aload index = ord(frame.code[frame.pc]) frame.pc += 1 value = frame.args[index] jassert_ref(value) frame.stack.append(value)
def invokevirtual(frame): index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 cp_item = frame.this_class.constant_pool[index] assert cp_item[0] == 10 # CONSTANT_Methodref klass_info = frame.this_class.constant_pool[cp_item[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_item[2]] assert name_and_type[0] == 12 # name_and_type_index klass_name = frame.this_class.constant_pool[klass_info[1]][1] method_name = frame.this_class.constant_pool[name_and_type[1]][1] method_signature = frame.this_class.constant_pool[name_and_type[2]][1] logger.debug("%s %s %s", klass_name, method_name, method_signature) klass = frame.vm.get_class(klass_name) method = klass.find_method(method_name, method_signature) nargs = args_count(method_signature) + 1 args = [None] * nargs while nargs > 0: value = frame.stack.pop() if type(value) is tuple and value[0] in ('long', 'double'): nargs -= 1 args[nargs - 1] = value nargs -= 1 logger.debug(frame.id) logger.debug(args) logger.debug(method_signature) jassert_ref(args[0]) if args[0] is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return if args[0][0] == "vm_ref": # vm owned object call vm_obj_call(frame, args, method_name, method_signature) return # ignore signute polimorphic method instance = frame.vm.heap[args[0][1]] klass = instance.java_class method = None while method is None and klass is not None: if method_name in klass.methods: if method_signature in klass.methods[method_name]: method = klass.methods[method_name][method_signature] break klass = klass.super_class assert method is not None assert klass is not None if method[0] & 0x0100 > 0: # is native? exec_native(frame, args, klass, method_name, method_signature) return obj_mon = None if method[0] & 0x0020 > 0: # is sync obj_mon = frame.vm.heap[args[0][1]] if "@monitor" in obj_mon.fields: if obj_mon.fields["@monitor"] == frame.thread: obj_mon.fields["@monitor_count"] += 1 else: index = 0 while index < len(args): a = args[index] if type(a) is tuple and a[0] in ('long', 'double'): index += 1 else: frame.stack.append(a) index += 1 raise SkipThreadCycle() else: obj_mon.fields["@monitor"] = frame.thread obj_mon.fields["@monitor_count"] = 1 m_args = [''] * method[1] m_args[0:len(args)] = args[0:len(args)] sub = Frame( frame.thread, klass, method, m_args, "InvVirt: %s %s in %s" % (method_name, method_signature, instance.java_class.this_name)) if obj_mon is not None: sub.monitor = obj_mon frame.thread.frame_stack.append(sub)
def invokespecial(frame): index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 cp_item = frame.this_class.constant_pool[index] assert cp_item[0] == 10 # CONSTANT_Methodref klass_info = frame.this_class.constant_pool[cp_item[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_item[2]] assert name_and_type[0] == 12 # name_and_type_index klass_name = frame.this_class.constant_pool[klass_info[1]][1] klass = frame.vm.get_class(klass_name) method_name = frame.this_class.constant_pool[name_and_type[1]][1] method_signature = frame.this_class.constant_pool[name_and_type[2]][1] method = klass.find_method(method_name, method_signature) logger.debug(klass_name) logger.debug(method_name) logger.debug(method_signature) logger.debug(frame.stack) if is_spec_lookup(frame.this_class, klass, method_name): method = None c = frame.this_class.super_class while method is None: if c is None: break if (method_name in c.methods and method_signature in c.methods[method_name]): method = c.methods[method_name][method_signature] klass = c break c = c.super_class assert method is not None nargs = args_count(method_signature) + 1 args = [None] * nargs while nargs > 0: value = frame.stack.pop() if type(value) is tuple and value[0] in ('long', 'double'): nargs -= 1 args[nargs - 1] = value nargs -= 1 assert len(args[0]) > 0 jassert_ref(args[0]) if args[0] is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return if method[0] & 0x0100 > 0: # is native? exec_native(frame, args, klass, method_name, method_signature) return obj_mon = None if method[0] & 0x0020 > 0: # is sync obj_mon = frame.vm.heap[args[0][1]] if "@monitor" in obj_mon.fields: if obj_mon.fields["@monitor"] == frame.thread: obj_mon.fields["@monitor_count"] += 1 else: index = 0 while index < len(args): a = args[index] if type(a) is tuple and a[0] in ('long', 'double'): index += 1 else: frame.stack.append(a) index += 1 raise SkipThreadCycle() else: obj_mon.fields["@monitor"] = frame.thread obj_mon.fields["@monitor_count"] = 1 m_args = [''] * method[1] m_args[0:len(args)] = args[0:len(args)] instance = frame.vm.heap[args[0][1]] logger.debug("InvokeSpec: %s:%s %s", method_name, method_signature, instance) sub = Frame(frame.thread, klass, method, m_args, "%s:%s %s" % (method_name, method_signature, instance)) if obj_mon is not None: sub.monitor = obj_mon frame.thread.frame_stack.append(sub)
def op_0x3a(frame): # astore index = ord(frame.code[frame.pc]) frame.pc += 1 value = frame.stack.pop() jassert_ref(value) frame.args[index] = value
def aload_3(frame): value = frame.args[3] jassert_ref(value) frame.stack.append(value)
def op_0x4c(frame): # astore_1 value = frame.stack.pop() jassert_ref(value) frame.args[1] = value
def op_0x4e(frame): # astore_3 value = frame.stack.pop() jassert_ref(value) frame.args[3] = value
def op_0xb9(frame): # invokeinterface index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1]) frame.pc += 2 count = ord(frame.code[frame.pc]) assert count > 0 frame.pc += 1 zero = ord(frame.code[frame.pc]) assert zero == 0 frame.pc += 1 cp_item = frame.this_class.constant_pool[index] assert cp_item[0] == 11 # CONSTANT_Methodref klass_info = frame.this_class.constant_pool[cp_item[1]] assert klass_info[0] == 7 # CONSTANT_Class_info name_and_type = frame.this_class.constant_pool[cp_item[2]] assert name_and_type[0] == 12 # name_and_type_index klass_name = frame.this_class.constant_pool[klass_info[1]][1] method_name = frame.this_class.constant_pool[name_and_type[1]][1] method_signature = frame.this_class.constant_pool[name_and_type[2]][1] logger.debug("%s %s %s", klass_name, method_name, method_signature) frame.vm.get_class(klass_name) nargs = args_count(method_signature) + 1 args = [None] * nargs while nargs > 0: value = frame.stack.pop() if type(value) is tuple and value[0] in ('long', 'double'): nargs -= 1 args[nargs - 1] = value nargs -= 1 logger.debug(args) logger.debug(method_signature) assert len(args[0]) > 0 jassert_ref(args[0]) if args[0] is None: frame.vm.raise_exception(frame, "java/lang/NullPointerException") return if args[0][0] == "vm_ref": # vm owned object call vm_obj_call(frame, args, method_name, method_signature) return # ignore signute polimorphic method instance = frame.vm.heap[args[0][1]] klass = instance.java_class method = None while method is None and klass is not None: if method_name in klass.methods: if method_signature in klass.methods[method_name]: method = klass.methods[method_name][method_signature] break klass = klass.super_class assert method is not None if method[0] & 0x0100 > 0: # is native? exec_native(frame, args, klass, method_name, method_signature) return obj_mon = None if method[0] & 0x0020 > 0: # is sync obj_mon = frame.vm.heap[args[0][1]] if "@monitor" in obj_mon.fields: if obj_mon.fields["@monitor"] == frame.thread: obj_mon.fields["@monitor_count"] += 1 else: index = 0 while index < len(args): a = args[index] if type(a) is tuple and a[0] in ('long', 'double'): index += 1 else: frame.stack.append(a) index += 1 raise SkipThreadCycle() else: obj_mon.fields["@monitor"] = frame.thread obj_mon.fields["@monitor_count"] = 1 m_args = [''] * method[1] m_args[0:len(args)] = args[0:len(args)] sub = Frame(frame.thread, klass, method, m_args, "InvInt: %s %s in %s" % (method_name, method_signature, instance.java_class.this_name)) if obj_mon is not None: sub.monitor = obj_mon frame.thread.frame_stack.append(sub) return
def op_0x2c(frame): # aload_2 value = frame.args[2] jassert_ref(value) frame.stack.append(value)
def op_0x2d(frame): # aload_3 value = frame.args[3] jassert_ref(value) frame.stack.append(value)
def astore(frame): index = ord(frame.code[frame.pc]) frame.pc += 1 value = frame.stack.pop() jassert_ref(value) frame.args[index] = value
def op_0x4b(frame): # astore_0 value = frame.stack.pop() jassert_ref(value) frame.args[0] = value
def astore_3(frame): value = frame.stack.pop() jassert_ref(value) frame.args[3] = value
def op_0x4d(frame): # astore_2 value = frame.stack.pop() jassert_ref(value) frame.args[2] = value
def aload(frame): index = ord(frame.code[frame.pc]) frame.pc += 1 value = frame.args[index] jassert_ref(value) frame.stack.append(value)
def areturn(frame): value = frame.stack.pop() jassert_ref(value) frame.ret = value frame.has_result = True frame.pc = len(frame.code) + 1