def mla(counts, klass_name): if len(counts) == 1: if klass_name in ('B', 'C', 'I', 'S', 'Z'): default = 0 elif klass_name == 'D': default = ('double', 0.0) elif klass_name == 'F': default = ('float', 0.0) elif klass_name == 'J': default = ('long', 0) elif klass_name[0] == 'L': default = None array_class = frame.vm.get_class('[' + klass_name) array = JArray(array_class, frame.vm) values = [default] * counts[0] array.values = values ref = frame.vm.add_to_heap(array) return ref else: name = '[' * len(counts) name += klass_name array_class = frame.vm.get_class(name) array = JArray(array_class, frame.vm) values = [None] * counts[0] for i in range(counts[0]): values[i] = mla(counts[1:], klass_name) array.values = values ref = frame.vm.add_to_heap(array) return ref
def newarray(frame): atype = ord(frame.code[frame.pc]) frame.pc += 1 count = frame.stack.pop() jassert_int(count) if count < 0: frame.vm.raise_exception(frame, "java/lang/NegativeArraySizeException") return values = None if atype in [10, 5, 8, 9, 4]: # int, char, byte, short, boolean values = [0] * count elif atype == 7: # double values = [("double", 0.0)] * count elif atype == 6: # float values = [("float", 0.0)] * count elif atype == 11: # long values = [("long", 0)] * count else: raise Exception( "Array creation for ATYPE {0} not yet supported".format(atype)) prims = { 4: "[Z", 5: "[C", 6: "[F", 7: "[D", 8: "[B", 9: "[S", 10: "[I", 11: "[J" } array_class = frame.vm.get_class(prims[atype]) jarray = JArray(array_class, frame.vm) jarray.values = values ref = frame.vm.add_to_heap(jarray) frame.stack.append(ref)
def newarray(frame): atype = ord(frame.code[frame.pc]) frame.pc += 1 count = frame.stack.pop() jassert_int(count) if count < 0: frame.vm.raise_exception(frame, "java/lang/NegativeArraySizeException") return values = None if atype in [10, 5, 8, 9, 4]: # int, char, byte, short, boolean values = [0]*count elif atype == 7: # double values = [("double", 0.0)] * count elif atype == 6: # float values = [("float", 0.0)] * count elif atype == 11: # long values = [("long", 0)] * count else: raise Exception("Array creation for ATYPE {0} not yet supported" .format(atype)) prims = {4: "[Z", 5: "[C", 6: "[F", 7: "[D", 8: "[B", 9: "[S", 10: "[I", 11: "[J"} array_class = frame.vm.get_class(prims[atype]) jarray = JArray(array_class, frame.vm) jarray.values = values ref = frame.vm.add_to_heap(jarray) frame.stack.append(ref)
def java_lang_Class_getDeclaredConstructors0__Z__Ljava_lang_reflect_Constructor_(frame, args): ref = args[0] assert type(ref) is tuple and ref[0] == "ref" o = frame.vm.heap[ref[1]] klass_name = o.fields["@CLASS_NAME"] klass = frame.vm.get_class(klass_name) c_klass = frame.vm.get_class("java/lang/reflect/Constructor") cons = [] if "<init>" in klass.methods: for m in klass.methods["<init>"]: c = c_klass.get_instance(frame.vm) c.fields["clazz"] = klass.heap_ref sign_ref = frame.vm.make_heap_string(m) c.fields["signature"] = sign_ref cref = frame.vm.add_to_heap(c) array_class = frame.vm.get_class("[Ljava/lang/Class;") params = JArray(array_class, frame.vm) params_ref = frame.vm.add_to_heap(params) c.fields["parameterTypes"] = params_ref cons.append(cref) array_class = frame.vm.get_class("[Ljava/lang/reflect/Constructor;") heap_item = JArray(array_class, frame.vm) heap_item.values = cons ref = frame.vm.add_to_heap(heap_item) frame.stack.append(ref)
def java_lang_Class_getDeclaredConstructors0__Z__Ljava_lang_reflect_Constructor_( frame, args): ref = args[0] assert type(ref) is tuple and ref[0] == "ref" o = frame.vm.heap[ref[1]] klass_name = o.fields["@CLASS_NAME"] klass = frame.vm.get_class(klass_name) c_klass = frame.vm.get_class("java/lang/reflect/Constructor") cons = [] if "<init>" in klass.methods: for m in klass.methods["<init>"]: c = c_klass.get_instance(frame.vm) c.fields["clazz"] = klass.heap_ref sign_ref = frame.vm.make_heap_string(m) c.fields["signature"] = sign_ref cref = frame.vm.add_to_heap(c) array_class = frame.vm.get_class("[Ljava/lang/Class;") params = JArray(array_class, frame.vm) params_ref = frame.vm.add_to_heap(params) c.fields["parameterTypes"] = params_ref cons.append(cref) array_class = frame.vm.get_class("[Ljava/lang/reflect/Constructor;") heap_item = JArray(array_class, frame.vm) heap_item.values = cons ref = frame.vm.add_to_heap(heap_item) frame.stack.append(ref)
def main(args): '''Init VM and run requested java application''' logging.basicConfig(filename='pyjvm.log', filemode='w', level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG) main_class = args.clazz[0] class_path = args.cp[0] params = args.param use_vm_cache = not args.no_vm_cache vm = None if use_vm_cache: vm = load_cached_vm(SERIALIZATION_ID) if vm is None: vm = vm_factory(class_path) vm.serialization_id = SERIALIZATION_ID if use_vm_cache: cache_vm(vm) else: vm.class_path = read_class_path(class_path) # lookup starter class & main method class_name = main_class.replace(".", "/") logger.debug("Starting with class %s", str(class_name)) java_class = vm.get_class(class_name) main_method = java_class.find_method("main", "([Ljava/lang/String;)V") if main_method is None: raise Exception("main method not found") logger.debug("Executing main") # create array of strings from command line parameters m_args = [''] * main_method[1] c_args = [] for param in params: ref = vm.make_heap_string(param) c_args.append(ref) heap_array = ("refarr", "java/lang/String", c_args) ref_arr = vm.add_to_heap(heap_array) array_class = vm.get_class("[Ljava/lang/String;") heap_item = JArray(array_class, vm) heap_item.values = c_args ref = vm.add_to_heap(heap_item) m_args[0] = ref # run main vm.run_vm(java_class, main_method, m_args) logger.debug("*** VM DONE ***")
def java_lang_Object_clone___Ljava_lang_Object_(frame, args): # TODO NPE o = frame.vm.heap[args[0][1]] if o.java_class.is_array: clone = JArray(o.java_class, frame.vm) clone.values = o.values[:] ref = frame.vm.add_to_heap(clone) frame.stack.append(ref) else: clone = o.java_class.get_instance(frame.vm) clone.fields = o.fields.copy() ref = frame.vm.add_to_heap(clone) frame.stack.append(ref)
def anewarray(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] == 7 # CONSTANT_Class klass_name = frame.this_class.constant_pool[cp_item[1]][1] assert type(klass_name) is unicode frame.vm.get_class(klass_name) # make sure it is loaded count = frame.stack.pop() jassert_int(count) if count < 0: frame.vm.raise_exception(frame, "java/lang/NegativeArraySizeException") return values = [None] * count array_class = frame.vm.get_class("[L" + klass_name + ";") jarray = JArray(array_class, frame.vm) jarray.values = values ref = frame.vm.add_to_heap(jarray) frame.stack.append(ref)
def java_lang_Class_getDeclaredFields0__Z__Ljava_lang_reflect_Field_(frame, args): ref = args[0] assert type(ref) is tuple and ref[0] == "ref" o = frame.vm.heap[ref[1]] klass_name = o.fields["@CLASS_NAME"] klass = frame.vm.get_class(klass_name) field_klass = frame.vm.get_class("java/lang/reflect/Field") fields = [] for field_name in klass.member_fields: field = field_klass.get_instance(frame.vm) name_ref = frame.vm.make_heap_string(field_name) field.fields["name"] = name_ref field.fields["clazz"] = klass.heap_ref field._name = field_name fref = frame.vm.add_to_heap(field) fields.append(fref) array_class = frame.vm.get_class("[Ljava/lang/reflect/Field;") heap_item = JArray(array_class, frame.vm) heap_item.values = fields ref = frame.vm.add_to_heap(heap_item) frame.stack.append(ref)
def make_heap_string(self, value): '''Take python string and put java.lang.String instance to heap. String is represented by char array in background. Reference in heap is returned. Global caching is supported for all strings (same string always has same reference in heap) ''' if value in self.global_strings: return self.global_strings[value] values = [] for c in value: values.append(ord(c)) array_class = self.get_class("[C") array = JArray(array_class, self) array.values = values arr_ref = self.add_to_heap(array) c = self.get_class("java/lang/String") o = c.get_instance(self) o.fields["value"] = arr_ref ref = self.add_to_heap(o) self.global_strings[value] = ref return ref
def java_lang_Class_getDeclaredFields0__Z__Ljava_lang_reflect_Field_( frame, args): ref = args[0] assert type(ref) is tuple and ref[0] == "ref" o = frame.vm.heap[ref[1]] klass_name = o.fields["@CLASS_NAME"] klass = frame.vm.get_class(klass_name) field_klass = frame.vm.get_class("java/lang/reflect/Field") fields = [] for field_name in klass.member_fields: field = field_klass.get_instance(frame.vm) name_ref = frame.vm.make_heap_string(field_name) field.fields["name"] = name_ref field.fields["clazz"] = klass.heap_ref field._name = field_name fref = frame.vm.add_to_heap(field) fields.append(fref) array_class = frame.vm.get_class("[Ljava/lang/reflect/Field;") heap_item = JArray(array_class, frame.vm) heap_item.values = fields ref = frame.vm.add_to_heap(heap_item) frame.stack.append(ref)
def main(): if not os.path.exists(PYJVMGUI_HOME): os.makedirs(PYJVMGUI_HOME) download_rt() app = QtWidgets.QApplication(sys.argv) '''Init VM and run requested java application''' logging.basicConfig(filename=os.path.join(PYJVMGUI_HOME, 'pyjvm.log'), filemode='w', level=logging.DEBUG) main_class = program_args.clazz[0] class_path = program_args.cp[0] params = program_args.param use_vm_cache = not program_args.no_vm_cache if program_args.clean_cache and os.path.isfile(VM_CACHE_PATH): print "WARNING: Cleaning vm-cache.bin (-cleancache)" os.remove(VM_CACHE_PATH) vm = None if use_vm_cache: vm = load_cached_vm(SERIALIZATION_ID) if vm is None: vm = vm_factory(class_path) vm.serialization_id = SERIALIZATION_ID if use_vm_cache: cache_vm(vm) else: for thread in vm.threads: PyJvmGui.THREAD_GUIS.append(PyJvmGui(ThreadExecutor(thread), len(PyJvmGui.THREAD_GUIS))) vm.class_path = read_class_path(class_path) # lookup starter class & main method class_name = main_class.replace(".", "/") logger.debug("Starting with class %s", str(class_name)) java_class = vm.get_class(class_name) main_method = java_class.find_method("main", "([Ljava/lang/String;)V") if main_method is None: raise Exception("main method not found") logger.debug("Executing main") # create array of strings from command line parameters m_args = [''] * main_method[1] c_args = [] for param in params: ref = vm.make_heap_string(param) c_args.append(ref) heap_array = ("refarr", "java/lang/String", c_args) ref_arr = vm.add_to_heap(heap_array) array_class = vm.get_class("[Ljava/lang/String;") heap_item = JArray(array_class, vm) heap_item.values = c_args ref = vm.add_to_heap(heap_item) m_args[0] = ref # run main vm.initialize_vm(java_class, main_method, m_args) sys.exit(app.exec_())