Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
Archivo: vm.py Proyecto: 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)
Ejemplo n.º 3
0
    def run_thread(self, thread, quota=-1):
        '''Run single thread according to quota.
        Quota is number of byte codes to be executed.
        Quota -1 runs entire thread in exclusive mode.

        For each byte code specific operation function is called.
        Operation can throw exception.
        Thread may be busy (e.g. monitor is not available).
        Returns from syncronized methods are handled.
        '''
        frame_stack = thread.frame_stack
        while len(frame_stack) > 0:
            frame = frame_stack[-1]  # get current
            if frame.pc < len(frame.code):
                op = frame.code[frame.pc]
                frame.cpc = frame.pc
                frame.pc += 1
                # Make function name to be called
                op_call = hex(ord(op))

                logger.debug("About to execute {2}: op_{0} ({3}) in {1}".format(
                    op_call, frame.id, frame.pc - 1, get_operation_name(op_call)))
                
                opt = get_operation(op_call)
                if opt is None:
                    raise Exception("Op ({0}) is not yet supported".format(
                        op_call))
                try:
                    try:
                        opt(frame)
                        logger.debug("Stack:" + str(frame.stack))
                    except SkipThreadCycle:
                        # Thread is busy, call the same operation later
                        frame.pc = frame.cpc
                        break
                except JavaException as jexc:
                    # Exception handling
                    ref = jexc.ref
                    exc = self.heap[ref[1]]
                    handled = False
                    while not handled:
                        for (start_pc, end_pc, handler_pc, catch_type,
                             type_name) in frame.method[3]:
                            if start_pc <= frame.cpc < end_pc and \
                                    self.object_of_klass(exc, type_name):
                                frame.pc = handler_pc
                                frame.stack.append(ref)
                                handled = True
                                break
                        if handled:
                            break
                        frame_stack.pop()
                        if len(frame_stack) == 0:
                            raise
                        frame = frame_stack[-1]

            else:
                # Frame is done
                frame_stack.pop()
                if frame.monitor is not None:
                    assert frame.monitor.fields["@monitor"] == frame.thread
                    frame.monitor.fields["@monitor_count"] -= 1
                    if frame.monitor.fields["@monitor_count"] == 0:
                        del frame.monitor.fields["@monitor"]
                        del frame.monitor.fields["@monitor_count"]
                        frame.monitor = None
                # handle possible return VALUE
                if frame.has_result:
                    if len(frame_stack) > 0:
                        frame_stack[-1].stack.append(frame.ret)

            if quota != -1:
                quota -= 1
                if quota == 0:
                    break
Ejemplo n.º 4
0
Archivo: vm.py Proyecto: MatevzFa/pyjvm
    def run_thread(self, thread, quota=-1):
        '''Run single thread according to quota.
        Quota is number of byte codes to be executed.
        Quota -1 runs entire thread in exclusive mode.
        For each byte code specific operation function is called.
        Operation can throw exception.
        Thread may be busy (e.g. monitor is not available).
        Returns from syncronized methods are handled.
        '''
        frame_stack = thread.frame_stack
        while len(frame_stack) > 0:
            frame = frame_stack[-1]  # get current
            if frame.pc < len(frame.code):
                op = frame.code[frame.pc]
                frame.cpc = frame.pc
                frame.pc += 1
                # Make function name to be called
                op_call = hex(ord(op))

                logger.debug(
                    "About to execute {2}: op_{0} ({3}) in {1}".format(
                        op_call, frame.id, frame.pc - 1,
                        get_operation_name(op_call)))

                opt = get_operation(op_call)
                if opt is None:
                    raise Exception(
                        "Op ({0}) is not yet supported".format(op_call))
                try:
                    try:
                        opt(frame)
                        logger.debug("Stack:" + str(frame.stack))
                    except SkipThreadCycle:
                        # Thread is busy, call the same operation later
                        frame.pc = frame.cpc
                        break
                except JavaException as jexc:
                    # Exception handling
                    ref = jexc.ref
                    exc = self.heap[ref[1]]
                    handled = False
                    while not handled:
                        for (start_pc, end_pc, handler_pc, catch_type,
                             type_name) in frame.method[3]:
                            if start_pc <= frame.cpc < end_pc and \
                                    self.object_of_klass(exc, type_name):
                                frame.pc = handler_pc
                                frame.stack.append(ref)
                                handled = True
                                break
                        if handled:
                            break
                        frame_stack.pop()
                        if len(frame_stack) == 0:
                            raise
                        frame = frame_stack[-1]

            else:
                # Frame is done
                frame_stack.pop()
                if frame.monitor is not None:
                    assert frame.monitor.fields["@monitor"] == frame.thread
                    frame.monitor.fields["@monitor_count"] -= 1
                    if frame.monitor.fields["@monitor_count"] == 0:
                        del frame.monitor.fields["@monitor"]
                        del frame.monitor.fields["@monitor_count"]
                        frame.monitor = None
                # handle possible return VALUE
                if frame.has_result:
                    if len(frame_stack) > 0:
                        frame_stack[-1].stack.append(frame.ret)

            if quota != -1:
                quota -= 1
                if quota == 0:
                    break