From 9bb1179929e5d7d41d6aedf02125dcfaacdbdca2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Fernandez Date: Wed, 6 Mar 2024 23:20:36 +0100 Subject: [PATCH] Add System class init and improve virtual method invocation --- src/Library/java/lang/System.cpp | 6 +++ src/Library/java/lang/System.h | 3 +- src/VM/Instructions/ReferenceInstructions.cpp | 42 +++++++++++++++++-- src/VM/VM.cpp | 22 +++++++++- src/VM/VM.h | 1 + 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/Library/java/lang/System.cpp b/src/Library/java/lang/System.cpp index 18a3b26..f9052e1 100644 --- a/src/Library/java/lang/System.cpp +++ b/src/Library/java/lang/System.cpp @@ -18,6 +18,7 @@ JCALL void lib_java_lang_System_registerNatives(NATIVE_ARGS) { registerNative("java/lang/System/arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", lib_java_lang_System_arraycopy); + registerNative("java/lang/System/initProperties", "(Ljava/util/Properties;)Ljava/util/Properties;", lib_java_lang_System_initProperties); } JCALL void lib_java_lang_System_arraycopy(NATIVE_ARGS) @@ -49,3 +50,8 @@ JCALL void lib_java_lang_System_arraycopy(NATIVE_ARGS) srcArray->data+(srcPosVar.data*bytes), lengthVar.data * bytes); } + +JCALL void lib_java_lang_System_initProperties(NATIVE_ARGS) +{ + thread->returnVar(thread->m_currentFrame->localVariables[0]); +} diff --git a/src/Library/java/lang/System.h b/src/Library/java/lang/System.h index 5ff89af..b9dce14 100644 --- a/src/Library/java/lang/System.h +++ b/src/Library/java/lang/System.h @@ -3,4 +3,5 @@ #include "Library/NativeDefs.h" JCALL void lib_java_lang_System_registerNatives(NATIVE_ARGS); -JCALL void lib_java_lang_System_arraycopy(NATIVE_ARGS); \ No newline at end of file +JCALL void lib_java_lang_System_arraycopy(NATIVE_ARGS); +JCALL void lib_java_lang_System_initProperties(NATIVE_ARGS); \ No newline at end of file diff --git a/src/VM/Instructions/ReferenceInstructions.cpp b/src/VM/Instructions/ReferenceInstructions.cpp index e32949e..941b21e 100644 --- a/src/VM/Instructions/ReferenceInstructions.cpp +++ b/src/VM/Instructions/ReferenceInstructions.cpp @@ -223,7 +223,7 @@ static void invokeVirtual(ClassInfo* classInfo, MethodInfo* methodInfo, VMThread } } - if (methodInfo->isNative()) { + if (targetMethod->isNative()) { thread->pushNativeStackFrame(targetClass, targetMethod, arguments.size()); } else { thread->pushStackFrameWithoutParams(targetClass, targetMethod); @@ -237,7 +237,7 @@ static void invokeVirtual(ClassInfo* classInfo, MethodInfo* methodInfo, VMThread } } - if (methodInfo->isNative()) + if (targetMethod->isNative()) { VM->executeNativeMethod(targetClass, targetMethod, heap, thread); thread->popFrame(); @@ -255,9 +255,43 @@ void invokevirtual(INSTRUCTION_ARGS) const std::string_view methodDescriptor = topFrame->constantPool->getString(nameAndTypeInfo->descriptorIndex); const std::string_view className = topFrame->constantPool->getString(cpClassInfo->nameIndex); ClassInfo* targetClassInfo = VM->getClass(className.data(), thread); - MethodInfo* methodInfo = targetClassInfo->findMethodWithNameAndDescriptor(methodName.data(), methodDescriptor.data()); + MethodInfo* foundMethod = targetClassInfo->findMethodWithNameAndDescriptor(methodName.data(), methodDescriptor.data()); + + MethodInfo* targetMethod = nullptr; + + // BEGIN BROL + if (foundMethod != nullptr) + { + targetMethod = foundMethod; + } else + { + + ClassInfo* currentClass = targetClassInfo; + while (currentClass->superClass != 0) { + CPClassInfo* ci = currentClass->constantPool->getClassInfo(currentClass->superClass); + [[maybe_unused]] const std::string_view superClass = currentClass->constantPool->getString(ci->nameIndex); + currentClass = VM->getClass(superClass.data(), thread); + if (currentClass != nullptr) { + foundMethod = currentClass->findMethodWithNameAndDescriptor(methodName.data(), + methodDescriptor.data()); + if (foundMethod != nullptr) { + targetClassInfo = currentClass; + targetMethod = foundMethod; + break; + } + } else { + break; + } + } + + if (foundMethod == nullptr) { + thread->internalError("Failed to get the correct method on the object.\n" + " Searching on superclass and generic search is not implemented yet."); + } + } + // END BROL - invokeVirtual(targetClassInfo, methodInfo, thread, VM, heap); + invokeVirtual(targetClassInfo, targetMethod, thread, VM, heap); printf("> Created new stack frame for virtual call on: %s.%s()\n", className.data(), methodName.data()); } diff --git a/src/VM/VM.cpp b/src/VM/VM.cpp index 0964856..d225480 100644 --- a/src/VM/VM.cpp +++ b/src/VM/VM.cpp @@ -42,7 +42,7 @@ void VM::start(const char* commandLineName) getClass("java/lang/Number", &m_mainThread); ClassInfo* classInfo = getClass("java/lang/Class", &m_mainThread); getClass("java/lang/String", &m_mainThread); - getClass("java/lang/System", &m_mainThread); + ClassInfo* systemClass = getClass("java/lang/System", &m_mainThread); getClass("java/lang/Thread", &m_mainThread); getClass("java/lang/ThreadGroup", &m_mainThread); getClass("java/lang/reflect/Field", &m_mainThread); @@ -50,11 +50,14 @@ void VM::start(const char* commandLineName) getClass("java/io/PrintStream", &m_mainThread); getClass("java/io/FilterOutputStream", &m_mainThread); getClass("java/io/OutputStream", &m_mainThread); + getClass("java/util/Properties", &m_mainThread); m_heap.setClassInfo(classInfo); const u4 threadGroupReference = createThreadGroupObject(&m_mainThread); m_mainThread.threadObject = createThreadObject(&m_mainThread, threadGroupReference); + + initSystemClass(systemClass, &m_mainThread); } u4 VM::createThreadGroupObject(VMThread* thread) @@ -334,7 +337,6 @@ void VM::runMain() Platform::exitProgram(6); } - Memory memory(1000, KIB(5)); ClassInfo* startupClass = getClass(m_configuration.mainClassName.data(), mainThread); MethodInfo* entryPoint = startupClass->findMethodWithNameAndDescriptor("main", "([Ljava/lang/String;)V"); @@ -358,6 +360,21 @@ void VM::runMain() printf("> Done executing\n"); } +void VM::initSystemClass(ClassInfo* systemClass, VMThread* thread) +{ + MethodInfo* initMethod = systemClass->findMethodWithNameAndDescriptor("initializeSystemClass", "()V"); + + thread->m_pc = 0; + thread->m_currentClass = systemClass; + thread->m_currentMethod = initMethod; + + thread->pushStackFrameSpecial(systemClass, initMethod, nullptr, &m_heap); + + printf("> Executing System init method...\n"); + executeLoop(thread); + printf("> Done executing System init method\n"); +} + void VM::shutdown() { PHYSFS_deinit(); @@ -371,3 +388,4 @@ void VM::checkType(const Variable var, const VariableType type, VMThread* thread thread->internalError("Error: TypeMismatch"); } } + diff --git a/src/VM/VM.h b/src/VM/VM.h index e1f7bf4..2e40fcb 100644 --- a/src/VM/VM.h +++ b/src/VM/VM.h @@ -57,6 +57,7 @@ class VM { return nullptr; } private: + void initSystemClass(ClassInfo* class_info, VMThread* vm_thread); inline static constexpr std::array m_instructions{{ // Constants {i_nop, 0, "nop", 0, nop},