Skip to content

Commit

Permalink
Improve java/lang/Thread support in VM
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandezseb committed Feb 3, 2024
1 parent 464868f commit 2aa0e86
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 13 deletions.
5 changes: 2 additions & 3 deletions src/ClassLoader/ClassLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ ClassInfo* ClassLoader::readClass(ByteArray& byteArray)

uint16_t interfacesCount = byteArray.readUnsignedShort();
classInfo->interfaces = readInterfaces(byteArray, interfacesCount);
classInfo->interfacesCount = interfacesCount;

uint16_t fieldsCount = byteArray.readUnsignedShort();
classInfo->fields = readFields(byteArray, classInfo->constantPool, fieldsCount);
Expand Down Expand Up @@ -298,7 +297,7 @@ ClassInfo* ClassLoader::readClass(const char* className, Memory* memory, [[maybe
return classInfo;
}

uint16_t* ClassLoader::readInterfaces(ByteArray& byteArray, uint16_t interfacesCount)
std::span<uint16_t> ClassLoader::readInterfaces(ByteArray& byteArray, uint16_t interfacesCount)
{
uint16_t* interfaces = (uint16_t*) m_memory->alloc(sizeof(uint16_t) * interfacesCount);

Expand All @@ -307,7 +306,7 @@ uint16_t* ClassLoader::readInterfaces(ByteArray& byteArray, uint16_t interfacesC
interfaces[currentInterface] = interfaceIndex;
}

return interfaces;
return {interfaces, interfacesCount};
}

FieldInfo** ClassLoader::readFields(ByteArray& byteArray, ConstantPool* constantPool, uint16_t fieldsCount)
Expand Down
2 changes: 1 addition & 1 deletion src/ClassLoader/ClassLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ClassLoader {
ConstantPool* readConstantPool(ByteArray& byteArray);
ConstantPoolItem* readConstantPoolItem(uint8_t tag, ByteArray& byteArray);
void parseDescriptor(const char* descriptor, MethodInfo* method);
uint16_t* readInterfaces(ByteArray& byteArray, uint16_t interfacesCount);
std::span<uint16_t> readInterfaces(ByteArray& byteArray, uint16_t interfacesCount);
FieldInfo** readFields(ByteArray& byteArray, ConstantPool* constantPool, uint16_t fieldsCount);
std::span<MethodInfo*> readMethods(ByteArray& byteArray, ConstantPool* constantPool, uint16_t methodCount);
ClassInfo* readClass(ByteArray& byteArray);
Expand Down
3 changes: 1 addition & 2 deletions src/Data/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ class ClassInfo {
uint16_t thisClass;
uint16_t superClass;

uint16_t* interfaces;
uint16_t interfacesCount;
std::span<uint16_t> interfaces;

FieldInfo** fields;
uint16_t fieldsCount;
Expand Down
25 changes: 25 additions & 0 deletions src/Library/java/lang/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@

#include "Thread.h"

[[nodiscard]] static const Object* getThisObjectReference(
VMThread* thread,
const JavaHeap* heap,
const VM* VM)
{
const StackFrame* currentFrame = thread->m_currentFrame;
const Variable var = currentFrame->localVariables[0];
VM->checkType(var, VariableType_REFERENCE, thread);
return heap->getObject(var.data);
}

JCALL void lib_java_lang_Thread_registerNatives(NATIVE_ARGS)
{
registerNative("java/lang/Thread/currentThread", "()Ljava/lang/Thread;", lib_java_lang_Thread_currentThread);
registerNative("java/lang/Thread/setPriority0", "(I)V", lib_java_lang_Thread_setPriority0);
}

JCALL void lib_java_lang_Thread_currentThread(NATIVE_ARGS)
Expand All @@ -26,3 +38,16 @@ JCALL void lib_java_lang_Thread_currentThread(NATIVE_ARGS)
returnFrame->pushObject(thread->threadObject);
}

JCALL void lib_java_lang_Thread_setPriority0(NATIVE_ARGS)
{
const Object* threadObject = getThisObjectReference(thread, heap, VM);


const StackFrame* currentFrame = thread->m_currentFrame;
const Variable argument = currentFrame->localVariables[1];
VM->checkType(argument, VariableType_INT, thread);

FieldData* field = threadObject->getField("priority", "I", heap);
field->data->data = argument.data;
}

3 changes: 2 additions & 1 deletion src/Library/java/lang/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
#include "Library/NativeDefs.h"

JCALL void lib_java_lang_Thread_registerNatives(NATIVE_ARGS);
JCALL void lib_java_lang_Thread_currentThread(NATIVE_ARGS);
JCALL void lib_java_lang_Thread_currentThread(NATIVE_ARGS);
JCALL void lib_java_lang_Thread_setPriority0(NATIVE_ARGS);
12 changes: 11 additions & 1 deletion src/VM/Instructions/ReferenceInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,17 @@ void instanceof(INSTRUCTION_ARGS)
const ClassInfo* targetClassInfo = VM->getClass(name.data(), thread);
if (targetClassInfo->isInterface())
{
thread->internalError("Instanceof not implemented yet for interface implementation checking");
for (const uint16_t interfaceIndex : classInfo->interfaces)
{
const CPClassInfo* interfaceInfo = classInfo->constantPool->getClassInfo(interfaceIndex);
const std::string_view interfaceName = classInfo->constantPool->getString(interfaceInfo->nameIndex);
if (interfaceName == name)
{
returnVal = 1;
break;
}
}
thread->m_currentFrame->pushInt(returnVal);
} else
// Check if it is a subclass
{
Expand Down
16 changes: 13 additions & 3 deletions src/VM/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ void VM::start()
u4 VM::createThreadGroupObject(VMThread* thread)
{
ClassInfo* threadGroupClass = getClass("java/lang/ThreadGroup", thread);
return m_heap.createObject(threadGroupClass, this);
const u4 threadGroupReference = m_heap.createObject(threadGroupClass, this);
const Object* threadGroupObject = m_heap.getObject(threadGroupReference);

const FieldData* maxPrioField = threadGroupObject->getField("maxPriority", "I", &m_heap);
maxPrioField->data->data = 10;


return threadGroupReference;
}

u4 VM::createThreadObject(VMThread* thread, const u4 threadGroupReference)
Expand All @@ -59,8 +66,11 @@ u4 VM::createThreadObject(VMThread* thread, const u4 threadGroupReference)
const u4 objectReference = m_heap.createObject(threadClass, this);
const Object* threadObject = m_heap.getObject(objectReference);

FieldData* field = threadObject->getField("group", "Ljava/lang/ThreadGroup;", &m_heap);
field->data->data = threadGroupReference;
const FieldData* groupField = threadObject->getField("group", "Ljava/lang/ThreadGroup;", &m_heap);
groupField->data->data = threadGroupReference;

const FieldData* priorityField = threadObject->getField("priority", "I", &m_heap);
priorityField->data->data = thread->priority;

return objectReference;
}
Expand Down
1 change: 1 addition & 0 deletions src/VM/VMThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class VMThread
ClassInfo* m_currentClass{nullptr};
std::string_view m_name;
u4 threadObject{0};
i1 priority{5};

explicit VMThread(const std::string_view name, const size_t frameSize) noexcept
: m_stack(frameSize), m_name(name)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/InstanceofTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public static void main(String[] args) {
throw new RuntimeException();
if (oNull instanceof String)
throw new RuntimeException();
// if (!(brol instanceof Serializable))
// throw new RuntimeException();
if (!(brol instanceof Serializable))
throw new RuntimeException();
// if (!(charArr instanceof char[]))
// throw new RuntimeException();
}
Expand Down

0 comments on commit 2aa0e86

Please sign in to comment.