Example #1
0
def java_lang_System_identityHashCode__Ljava_lang_Object__I(frame, args):
    ref = args[0]
    if ref is None:
        frame.stack.append(0)
        return
    assert type(ref) is tuple
    assert ref[0] == "ref"

    o = frame.vm.heap[ref[1]]
    klass = o.java_class
    method = klass.find_method("hashCode", "()I")

    if method[0] & 0x0100 > 0:
        # assuming native call to object's hashCode, get heap id
        frame.stack.append(ref[1])
        return

    pvm_thread = Thread(frame.vm, frame.vm.top_thread_ref)
    pvm_thread.is_alive = True
    m_args = [None] * method[1]
    m_args[0] = ref
    sub = Frame(pvm_thread, klass, method, m_args, "call get hashCode")
    pvm_thread.frame_stack.append(sub)
    frame.vm.run_thread(pvm_thread)
    assert sub.has_result
    frame.stack.append(sub.ret)
Example #2
0
File: vm.py Project: MatevzFa/pyjvm
    def __init__(self, _class_path="."):
        logger.debug("Creating VM")

        # Major memory structures
        self.perm_gen = {}
        self.heap = {}
        self.heap_next_id = 1
        # todo clean up self.cache_klass_klass = {}
        self.global_strings = {}

        # Handle for linked list of threads
        self.threads_queue = deque()
        self.threads = []
        self.non_daemons = 0

        self.top_group = None
        self.top_thread = None
        self.top_group_ref = None
        self.top_thread_ref = None

        self.class_path = read_class_path(_class_path)

        self.init_default_thread()

        # Load System and init major fields
        system_class = self.get_class("java/lang/System")

        # Set System.props to vm owned object
        system_class.static_fields["props"][1] = (
            "vm_ref", VM_OBJECTS["System.Properties"])

        # STDout initialization using vm owned object
        ps_class = self.get_class("java/io/PrintStream")
        ps_object = ps_class.get_instance(self)
        ps_ref = self.add_to_heap(ps_object)
        method = ps_class.find_method("<init>", "(Ljava/io/OutputStream;)V")
        std_out_ref = ("vm_ref", VM_OBJECTS["Stdout.OutputStream"])
        thread = Thread(self, None)
        frame = Frame(thread, ps_class, method, [ps_ref, std_out_ref],
                      "PrintStream init")
        thread.frame_stack.append(frame)

        logger.debug("Run PrintStream init")
        self.run_thread(thread)  # Run exclusive thread
        # <--thread added to the VM at this point
        system_class.static_fields["out"][1] = ps_ref

        system_class.static_fields["in"][1] = \
            ("vm_ref", VM_OBJECTS["Stdin.InputputStream"])

        # Additional parameters
        system_class.static_fields["lineSeparator"][1] = \
            self.make_heap_string("\n")

        # Load additional classes to speed up booting
        self.touch_classes()

        self.initialized = True

        logger.debug("VM created")
Example #3
0
File: vm.py Project: MatevzFa/pyjvm
    def initialize_vm(self, main_klass, method, m_args):
        """
        Run initialized vm with specific method of a class.
        This is class entered from command line. Method is looked up
        void main(String args[]).
        For more details see methods.txt in docs.
        :param main_klass:
        :param method:
        :param m_args:
        :return:
        """
        t_klass = self.get_class("java/lang/Thread")
        t = t_klass.get_instance(self)
        t.fields["priority"] = 5
        t.fields["name"] = self.make_heap_string("main")
        t.fields["blockerLock"] = self.add_to_heap(
            self.get_class("java/lang/Object").get_instance(self))
        t_ref = self.add_to_heap(t)
        t.fields["group"] = self.top_group_ref

        pvm_thread = Thread(self, t_ref)
        pvm_thread.is_alive = True
        frame = Frame(pvm_thread, main_klass, method, m_args, "main")
        pvm_thread.frame_stack.append(frame)

        self.add_thread(pvm_thread)
        logger.debug("run thread pool")
Example #4
0
File: vm.py Project: MatevzFa/pyjvm
    def init_default_thread(self):
        '''Create initial thread group and thread.
        Both are java's objects
        '''
        tg_klass = self.get_class("java/lang/ThreadGroup")
        t_klass = self.get_class("java/lang/Thread")
        tg = tg_klass.get_instance(self)
        t = t_klass.get_instance(self)

        tg.fields["name"] = self.make_heap_string("system")
        tg.fields["maxPriority"] = 10
        t.fields["priority"] = 5
        t.fields["name"] = self.make_heap_string("system-main")
        t.fields["blockerLock"] = self.add_to_heap(
            self.get_class("java/lang/Object").get_instance(self))

        tg_ref = self.add_to_heap(tg)
        t_ref = self.add_to_heap(t)
        t.fields["group"] = tg_ref

        # Add thread to threadgroup; call byte code of void add(Thread)
        pvm_thread = Thread(self, t_ref)
        pvm_thread.is_alive = True
        method = tg_klass.find_method("add", "(Ljava/lang/Thread;)V")
        args = [None] * method[1]
        args[0] = tg_ref
        args[1] = t_ref
        frame = Frame(pvm_thread, tg_klass, method, args, "system tg init")
        pvm_thread.frame_stack.append(frame)
        self.run_thread(pvm_thread)

        self.top_group = tg
        self.top_thread = t
        self.top_group_ref = tg_ref
        self.top_thread_ref = t_ref
Example #5
0
def java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction__Ljava_lang_Object_(
        frame, args):
    ref = args[0]
    assert type(ref) is tuple and ref[0] == "ref"
    o = frame.vm.heap[ref[1]]
    klass = o.java_class
    method = klass.find_method("run", "()Ljava/lang/Object;")
    args = [None] * method[1]
    args[0] = ref
    sub = Frame(frame.thread, klass, method, args,
                "RUN call in java_security_AccessController_doPrivileged")
    frame.thread.frame_stack.append(sub)
Example #6
0
def java_lang_Thread_start0___V(frame, args):
    '''Create new thread with one's void run()
    see thread.txt for details
    '''
    t_ref = args[0]
    o = frame.vm.heap[t_ref[1]]
    run = o.java_class.find_method("run", "()V")
    assert run is not None

    pvm_thread = Thread(frame.vm, t_ref)
    pvm_thread.is_alive = True
    m_args = [None] * run[1]
    m_args[0] = t_ref
    sub = Frame(pvm_thread, o.java_class, run, m_args, "Thread")
    pvm_thread.frame_stack.append(sub)
    frame.vm.add_thread(pvm_thread)
Example #7
0
File: vm.py Project: MatevzFa/pyjvm
    def run_static_constructor(self, java_class):
        '''Static constructor is run for every class loaded by class loader.
        It is executed in thread exclusive mode.
        '''
        logger.debug("Running static constructor for %s", java_class.this_name)
        method = java_class.static_contructor()
        if method is None:
            logger.debug("No static constructor for %s", java_class.this_name)
            return
        pvm_thread = Thread(self, self.top_thread_ref)
        pvm_thread.is_alive = True
        frame = Frame(pvm_thread, java_class, method, [None] * method[1],
                      "<clinit:{0}>".format(java_class.this_name))
        pvm_thread.frame_stack.append(frame)
        self.run_thread(pvm_thread)

        logger.debug("Finished with static constructor for %s",
                     java_class.this_name)
Example #8
0
File: vm.py Project: MatevzFa/pyjvm
    def raise_exception(self, frame, name):
        '''Util method to raise an exception based on name.
        e.g. java.lang.NullPointerException

        Exception is created on heap and throw op is called
        '''
        ex_klass = self.get_class(name)
        ex = ex_klass.get_instance(self)
        ref = self.add_to_heap(ex)

        method = ex_klass.find_method("<init>", "()V")
        m_args = [None] * method[1]
        m_args[0] = ref

        pvm_thread = Thread(self, None)
        pvm_thread.is_alive = True
        sub = Frame(pvm_thread, ex_klass, method, m_args, "exinit")
        pvm_thread.frame_stack.append(sub)
        self.run_thread(pvm_thread)

        frame.stack.append(ref)
        get_operation('0xbf')(frame)
def sun_reflect_NativeConstructorAccessorImpl_newInstance0__Ljava_lang_reflect_Constructor__Ljava_lang_Object__Ljava_lang_Object_(frame, args):
    '''Create instance of a class, with constructor call'''
    ref = args[0]
    params = args[1]
    assert type(ref) is tuple and ref[0] == "ref"
    assert params is None or len(params) == 0
    o = frame.vm.heap[ref[1]]
    klass_klass = frame.vm.heap[o.fields["clazz"][1]]
    clazz = frame.vm.get_class(klass_klass.fields["@CLASS_NAME"])
    signature = str_to_string(frame.vm, o.fields["signature"])
    assert signature == "()V"
    instance = clazz.get_instance(frame.vm)
    iref = frame.vm.add_to_heap(instance)
    frame.stack.append(iref)
    method = clazz.find_method("<init>", signature)

    # actully running constructor in exclusive mode
    pvm_thread = Thread(frame.vm, frame.vm.top_thread_ref)
    pvm_thread.is_alive = True
    m_args = [None]*method[1]
    m_args[0] = iref
    sub = Frame(pvm_thread, clazz, method, m_args, "nativ instance0")
    pvm_thread.frame_stack.append(sub)
    frame.vm.run_thread(pvm_thread)
Example #10
0
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)
Example #11
0
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)
Example #12
0
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)
Example #13
0
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
Example #14
0
def invokestatic(frame):
    index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1])
    frame.pc += 2
    cp_methodref = frame.this_class.constant_pool[index]
    assert cp_methodref[0] == 10  # CONSTANT_Methodref
    klass_info = frame.this_class.constant_pool[cp_methodref[1]]
    assert klass_info[0] == 7  # CONSTANT_Class_info
    name_and_type = frame.this_class.constant_pool[cp_methodref[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]
    assert klass_name is not None
    assert method_name is not None
    assert method_signature is not None

    if klass_name == "sun/misc/VM" and method_name == "isBooted":
        # shortcut, to be remvoed
        frame.stack.append(1)
        return

    if (klass_name == "sun/reflect/Reflection" and
            method_name == "registerMethodsToFilter"):
        logger.debug("Ignoring registerMethodsToFilter")
        frame.stack.pop()
        frame.stack.pop()
        return

    if (klass_name == "sun/misc/SharedSecrets" and
            method_name == "getJavaLangAccess"):
        # use vm owned object instead of constructing real one
        frame.vm.get_class("sun/misc/JavaLangAccess")
        frame.stack.append(("vm_ref", VM_OBJECTS["JavaLangAccess"]))
        return

    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)
    assert method is not None
    assert method[0] & 0x0008 > 0  # make sure this is static method

    obj_mon = None
    if method[0] & 0x0020:
        obj_mon = frame.vm.heap[klass.heap_ref[1]]
        if "@monitor" in obj_mon.fields:
            if obj_mon.fields["@monitor"] == frame.thread:
                obj_mon.fields["@monitor_count"] += 1
            else:
                raise SkipThreadCycle()
        else:
            obj_mon.fields["@monitor"] = frame.thread
            obj_mon.fields["@monitor_count"] = 1

    nargs = args_count(method_signature)
    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

    if method[0] & 0x0100 > 0:  # is native?
        exec_native(frame, args, klass, method_name, method_signature)
        return

    m_args = [''] * method[1]
    m_args[0:len(args)] = args[0:len(args)]

    logger.debug("InvStatic: %s %s in %s", method_name, method_signature,
                 klass_name)
    if method_name == "countBits":
        frame.stack.append(5)
        return

    sub = Frame(frame.thread, klass, method, m_args,
                "InvStatic: %s %s in %s" % (method_name, method_signature,
                                            klass_name))
    if obj_mon is not None:
        sub.monitor = obj_mon
    frame.thread.frame_stack.append(sub)
Example #15
0
def invokestatic(frame):
    index = (ord(frame.code[frame.pc]) << 8) + ord(frame.code[frame.pc + 1])
    frame.pc += 2
    cp_methodref = frame.this_class.constant_pool[index]
    assert cp_methodref[0] == 10  # CONSTANT_Methodref
    klass_info = frame.this_class.constant_pool[cp_methodref[1]]
    assert klass_info[0] == 7  # CONSTANT_Class_info
    name_and_type = frame.this_class.constant_pool[cp_methodref[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]
    assert klass_name is not None
    assert method_name is not None
    assert method_signature is not None

    if klass_name == "sun/misc/VM" and method_name == "isBooted":
        # shortcut, to be remvoed
        frame.stack.append(1)
        return

    if (klass_name == "sun/reflect/Reflection"
            and method_name == "registerMethodsToFilter"):
        logger.debug("Ignoring registerMethodsToFilter")
        frame.stack.pop()
        frame.stack.pop()
        return

    if (klass_name == "sun/misc/SharedSecrets"
            and method_name == "getJavaLangAccess"):
        # use vm owned object instead of constructing real one
        frame.vm.get_class("sun/misc/JavaLangAccess")
        frame.stack.append(("vm_ref", VM_OBJECTS["JavaLangAccess"]))
        return

    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)
    assert method is not None
    assert method[0] & 0x0008 > 0  # make sure this is static method

    obj_mon = None
    if method[0] & 0x0020:
        obj_mon = frame.vm.heap[klass.heap_ref[1]]
        if "@monitor" in obj_mon.fields:
            if obj_mon.fields["@monitor"] == frame.thread:
                obj_mon.fields["@monitor_count"] += 1
            else:
                raise SkipThreadCycle()
        else:
            obj_mon.fields["@monitor"] = frame.thread
            obj_mon.fields["@monitor_count"] = 1

    nargs = args_count(method_signature)
    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

    if method[0] & 0x0100 > 0:  # is native?
        exec_native(frame, args, klass, method_name, method_signature)
        return

    m_args = [''] * method[1]
    m_args[0:len(args)] = args[0:len(args)]

    logger.debug("InvStatic: %s %s in %s", method_name, method_signature,
                 klass_name)
    if method_name == "countBits":
        frame.stack.append(5)
        return

    sub = Frame(
        frame.thread, klass, method, m_args,
        "InvStatic: %s %s in %s" % (method_name, method_signature, klass_name))
    if obj_mon is not None:
        sub.monitor = obj_mon
    frame.thread.frame_stack.append(sub)