예제 #1
0
def test_native_method(std_loader):
    machine = Machine(std_loader)
    action = Invoke(
        'java/lang/System',
        MethodKey(
            'currentTimeMillis',
            '()J'
        ),
        []
    )
    with pytest.raises(NativeNotSupported):
        machine.act(action)
예제 #2
0
def test_method_from_super_class(std_loader):
    instance = std_loader.default_instance(NPE_CLASS_NAME)
    action = Invoke(
        NPE_CLASS_NAME,
        MethodKey(
            'toString',
            '()Ljava/lang/String;'
        ),
        [instance]
    )
    machine = Machine(std_loader)
    machine.act(action)
    assert machine.frames.peek().method_name == 'toString'
예제 #3
0
def run(loader, main_class_name, echo=None):
    """Run the class named `main_class_name` using `loader`

    :param loader: ClassLoader, the loader to use
    :param main_class_name: str, the name of the main class
    :param echo: a print-like method that, if provided, will be used for tracing execution
    """
    machine = Machine(loader, echo=echo)

    class_ = loader.get_the_class(main_class_name)
    key = MethodKey('main', '([Ljava/lang/String;)V')
    method = class_.methods[key]
    frame = Frame.from_class_and_method(class_, method)

    machine.frames.push(frame)
    machine.run()
예제 #4
0
def test_invoke_v():
    method_name = 'method_name'
    class_name = 'class_name'

    consts = ConstantPool()
    descriptor = '(II)V'
    key = MethodKey(method_name, descriptor)
    no_op = Instruction.create('nop')

    method = BytecodeMethod(
        name='method_name',
        descriptor='(II)V',
        max_locals=5,
        max_stack=5,
        instructions=[no_op, no_op],
        args=[Integer, Integer],
    )

    jvm_class = JvmClass(
        class_name,
        RootObjectType.refers_to,
        consts,
        methods={
            key: method
        }
    )

    method_ref = consts.create_method_ref(class_name, method_name, descriptor)
    instruction = constant_instruction('invokevirtual', method_ref)
    loader = FixedClassLoader({
        class_name: jvm_class
    })

    instance = loader.default_instance(class_name)
    arg_value = SOME_INT
    arguments = [instance, arg_value, arg_value]
    reversed_arguments = list(reversed(arguments))
    assert_instruction(
        constants=consts,
        loader=loader,
        instruction=instruction,
        op_stack=reversed_arguments,
        expected=[
            Pop(3),
            Invoke(class_name, key, arguments)
        ]
    )
예제 #5
0
    def _first_class_load(self, class_):
        """Perform class loading operations

        When a class is accessed for the first time we need to:
         - Initialize the static fields to their default values
         - Call the `<clinit>` method for the class
        """
        try:
            key = MethodKey('<clinit>', '()V')
            method = class_.methods[key]
        except KeyError:
            return
        temp_stack = Stack()
        temp_stack.push(Frame.from_class_and_method(class_, method))

        old_stack = self.frames
        self.frames = temp_stack
        self.run()
        self.frames = old_stack
예제 #6
0
 def _is_stack_trace(self, class_name, method_key):
     key = MethodKey('fillInStackTrace', '(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;')
     return class_name == 'java/lang/VMThrowable' and method_key == key
예제 #7
0
def key_from_method_ref(ref):
    """Extract a MethodKey from a jawa method reference constant"""
    name = ref.name_and_type.name.value
    descriptor = ref.name_and_type.descriptor.value
    return MethodKey(name, descriptor)
예제 #8
0
def key_from_method(method):
    """Extract a MethodKey from a jawa method"""
    return MethodKey(method.name.value, method.descriptor.value)
예제 #9
0
    IncrementProgramCounter
from pyjvm.core.class_loaders import FixedClassLoader
from pyjvm.core.frame import Frame
from pyjvm.core.jvm_class import Handlers, ExceptionHandler, JvmClass, MethodKey, BytecodeMethod
from pyjvm.core.jvm_types import Integer, ArrayReferenceType, RootObjectType, ObjectReferenceType
from pyjvm.core.machine import Machine, Unhandled, NativeNotSupported
from pyjvm.utils.utils import named_tuple_replace
from test.utils import SOME_INT

COMPLEX_CLASS_NAME = 'class_name'
EXCEPTION_NAME = 'some_exception'
FIELD_NAME = 'some_field'
FIELD_DESCRIPTOR = 'I'
METHOD_NAME = 'some_method'
METHOD_DESCRIPTOR = '(II)I'
METHOD_KEY = MethodKey(METHOD_NAME, METHOD_DESCRIPTOR)
HANDLER = ExceptionHandler(
    start_pc=2,
    end_pc=3,
    handler_pc=4,
    catch_type=EXCEPTION_NAME
)

METHOD = BytecodeMethod(
    name='method_name',
    descriptor='(II)V',
    instructions=[
        named_tuple_replace(Instruction.create('nop'), pos=i) for i in range(5)
    ],
    max_locals=5,
    max_stack=15,