Skip to content

Commit

Permalink
Refactor native function execution
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandezseb committed Mar 15, 2024
1 parent 403798c commit e10c0d5
Show file tree
Hide file tree
Showing 36 changed files with 266 additions and 260 deletions.
7 changes: 1 addition & 6 deletions src/Library/NativeDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,4 @@

#include "VM/Native.h"

#define JCALL extern "C"

#define NATIVE_ARGS \
[[maybe_unused]] JavaHeap* heap, \
[[maybe_unused]] VMThread* thread, \
[[maybe_unused]] VM* VM
#define JCALL extern "C"
12 changes: 6 additions & 6 deletions src/Library/java/io/FileDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@

#include "FileDescriptor.h"

JCALL void lib_java_io_FileDescriptor_initIDs(NATIVE_ARGS)
JCALL void lib_java_io_FileDescriptor_initIDs(const NativeArgs& args)
{
printf("[Running initIDs from FileDescriptor]\n");
}

JCALL void lib_java_io_FileDescriptor_set(NATIVE_ARGS)
JCALL void lib_java_io_FileDescriptor_set(const NativeArgs& args)
{
const StackFrame* currentFrame = thread->m_currentFrame;
const StackFrame* currentFrame = args.thread->m_currentFrame;
const Variable var = currentFrame->localVariables[0];

FILE* filePtr = nullptr;
Expand All @@ -38,12 +38,12 @@ JCALL void lib_java_io_FileDescriptor_set(NATIVE_ARGS)
filePtr = stderr;
break;
default:
thread->internalError("Filedescriptor not found");
args.thread->internalError("Filedescriptor not found");
}

u8 handle = reinterpret_cast<u8>(filePtr);

const auto parts = reinterpret_cast<u4*>(&handle);
thread->returnVar(Variable{VariableType_LONG, parts[1]});
thread->returnVar(Variable{VariableType_LONG, parts[0]});
args.thread->returnVar(Variable{VariableType_LONG, parts[1]});
args.thread->returnVar(Variable{VariableType_LONG, parts[0]});
}
4 changes: 2 additions & 2 deletions src/Library/java/io/FileDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

#include "Library/NativeDefs.h"

JCALL void lib_java_io_FileDescriptor_initIDs(NATIVE_ARGS);
JCALL void lib_java_io_FileDescriptor_set(NATIVE_ARGS);
JCALL void lib_java_io_FileDescriptor_initIDs(const NativeArgs& args);
JCALL void lib_java_io_FileDescriptor_set(const NativeArgs& args);
2 changes: 1 addition & 1 deletion src/Library/java/io/FileInputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#include "FileInputStream.h"

JCALL void lib_java_io_FileInputStream_initIDs(NATIVE_ARGS)
JCALL void lib_java_io_FileInputStream_initIDs(const NativeArgs& args)
{
printf("[Running initIDs from FileInputStream]\n");
}
2 changes: 1 addition & 1 deletion src/Library/java/io/FileInputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

#include "Library/NativeDefs.h"

JCALL void lib_java_io_FileInputStream_initIDs(NATIVE_ARGS);
JCALL void lib_java_io_FileInputStream_initIDs(const NativeArgs& args);
2 changes: 1 addition & 1 deletion src/Library/java/io/FileOutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#include "FileOutputStream.h"

JCALL void lib_java_io_FileOutputStream_initIDs(NATIVE_ARGS)
JCALL void lib_java_io_FileOutputStream_initIDs(const NativeArgs& args)
{
printf("[Running initIDs from FileOutputStream]\n");
}
2 changes: 1 addition & 1 deletion src/Library/java/io/FileOutputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

#include "Library/NativeDefs.h"

JCALL void lib_java_io_FileOutputStream_initIDs(NATIVE_ARGS);
JCALL void lib_java_io_FileOutputStream_initIDs(const NativeArgs& args);
124 changes: 62 additions & 62 deletions src/Library/java/lang/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
return heap->getClassObject(var.data);
}

JCALL void lib_java_lang_Class_registerNatives(NATIVE_ARGS)
JCALL void lib_java_lang_Class_registerNatives(const NativeArgs& args)
{
registerNative("java/lang/Class/getPrimitiveClass", "(Ljava/lang/String;)Ljava/lang/Class;",
lib_java_lang_Class_getPrimitiveClass);
Expand All @@ -55,140 +55,140 @@ JCALL void lib_java_lang_Class_registerNatives(NATIVE_ARGS)
registerNative("java/lang/Class/isInterface", "()Z", lib_java_lang_Class_isInterface);
}

JCALL void lib_java_lang_Class_getPrimitiveClass(NATIVE_ARGS)
JCALL void lib_java_lang_Class_getPrimitiveClass(const NativeArgs& args)
{
const Object* strObject = getThisObjectReference(thread, heap, VM);
const std::string_view typeString = heap->getStringContent(strObject);
const Object* strObject = getThisObjectReference(args.thread, args.heap, args.vm);
const std::string_view typeString = args.heap->getStringContent(strObject);
u4 classRef = 0;
if (typeString == "float")
{
ClassInfo* classInfo = VM->getClass("java/lang/Float", thread);
classRef = heap->createClassObject(classInfo, VM, "java/lang/Float");
ClassInfo* classInfo = args.vm->getClass("java/lang/Float", args.thread);
classRef = args.heap->createClassObject(classInfo, args.vm, "java/lang/Float");
}
else if (typeString == "int")
{
ClassInfo* classInfo = VM->getClass("java/lang/Integer", thread);
classRef = heap->createClassObject(classInfo, VM, "java/lang/Integer");
ClassInfo* classInfo = args.vm->getClass("java/lang/Integer", args.thread);
classRef = args.heap->createClassObject(classInfo, args.vm, "java/lang/Integer");
}
else if (typeString == "double")
{
ClassInfo* classInfo = VM->getClass("java/lang/Double", thread);
classRef = heap->createClassObject(classInfo, VM, "java/lang/Double");
ClassInfo* classInfo = args.vm->getClass("java/lang/Double", args.thread);
classRef = args.heap->createClassObject(classInfo, args.vm, "java/lang/Double");
}
else if (typeString == "char")
{
ClassInfo* classInfo = VM->getClass("java/lang/Character", thread);
classRef = heap->createClassObject(classInfo, VM, "java/lang/Character");
ClassInfo* classInfo = args.vm->getClass("java/lang/Character", args.thread);
classRef = args.heap->createClassObject(classInfo, args.vm, "java/lang/Character");
}
else if (typeString == "boolean")
{
ClassInfo* classInfo = VM->getClass("java/lang/Boolean", thread);
classRef = heap->createClassObject(classInfo, VM, "java/lang/Boolean");
ClassInfo* classInfo = args.vm->getClass("java/lang/Boolean", args.thread);
classRef = args.heap->createClassObject(classInfo, args.vm, "java/lang/Boolean");
}
else
{
thread->internalError("Typestring not found");
args.thread->internalError("Typestring not found");
}
thread->returnVar(Variable{VariableType_REFERENCE, classRef});
args.thread->returnVar(Variable{VariableType_REFERENCE, classRef});
}

JCALL void lib_java_lang_Class_desiredAssertionStatus0(NATIVE_ARGS)
JCALL void lib_java_lang_Class_desiredAssertionStatus0(const NativeArgs& args)
{
thread->returnVar(Variable{VariableType_INT, 0});
args.thread->returnVar(Variable{VariableType_INT, 0});
}

JCALL void lib_java_lang_Class_getName0(NATIVE_ARGS)
JCALL void lib_java_lang_Class_getName0(const NativeArgs& args)
{
const ClassObject* classObject = getThisClassObjectReference(thread, heap, VM);
const ClassObject* classObject = getThisClassObjectReference(args.thread, args.heap, args.vm);
const std::string_view name = classObject->name;
const u4 stringObject = heap->createString(name.data(), VM);
thread->returnVar(Variable{VariableType_REFERENCE, stringObject});
const u4 stringObject = args.heap->createString(name.data(), args.vm);
args.thread->returnVar(Variable{VariableType_REFERENCE, stringObject});
}

JCALL void lib_java_lang_Class_forName0(NATIVE_ARGS)
JCALL void lib_java_lang_Class_forName0(const NativeArgs& args)
{
const StackFrame* currentFrame = thread->m_currentFrame;
const StackFrame* currentFrame = args.thread->m_currentFrame;
const Variable var = currentFrame->localVariables[0];
VM->checkType(var, VariableType_REFERENCE, thread);
const std::string_view className = heap->getStringContent(var.data);
args.vm->checkType(var, VariableType_REFERENCE, args.thread);
const std::string_view className = args.heap->getStringContent(var.data);
std::string canonicalClassName = std::string(className.data(), className.size());
std::replace(canonicalClassName.begin(), canonicalClassName.end(),
'.', '/');

// TODO: Check initialize bool
const Variable var2 = currentFrame->localVariables[1];
VM->checkType(var2, VariableType_INT, thread);
args.vm->checkType(var2, VariableType_INT, args.thread);
if (var2.data == 0u)
{
thread->internalError("Loading class without initialization is not implemente yet");
args.thread->internalError("Loading class without initialization is not implemente yet");
}

// TODO: Use custom classloader if defined
const Variable var3 = currentFrame->localVariables[2];
VM->checkType(var3, VariableType_REFERENCE, thread);
args.vm->checkType(var3, VariableType_REFERENCE, args.thread);
if (var3.data != 0u)
{
thread->internalError("Use of custom classloader not implemented yet");
args.thread->internalError("Use of custom classloader not implemented yet");
}

ClassInfo* classInfo = VM->getClass(canonicalClassName, thread);
const u4 classObjectRef = heap->createClassObject(classInfo, VM, canonicalClassName);
thread->returnVar(Variable{VariableType_REFERENCE, classObjectRef});
ClassInfo* classInfo = args.vm->getClass(canonicalClassName, args.thread);
const u4 classObjectRef = args.heap->createClassObject(classInfo, args.vm, canonicalClassName);
args.thread->returnVar(Variable{VariableType_REFERENCE, classObjectRef});
}

JCALL void lib_java_lang_Class_getDeclaredFields0(NATIVE_ARGS)
JCALL void lib_java_lang_Class_getDeclaredFields0(const NativeArgs& args)
{
const ClassObject* classObject = getThisClassObjectReference(thread, heap, VM);
const StackFrame* currentFrame = thread->m_currentFrame;
const ClassObject* classObject = getThisClassObjectReference(args.thread, args.heap, args.vm);
const StackFrame* currentFrame = args.thread->m_currentFrame;
// TODO: Use publicOnlyBooleanVar
[[maybe_unused]] const Variable publicOnlyBooleanVar = currentFrame->localVariables[1];
const u4 arraySize = classObject->classClassInfo->fieldsCount;
const u4 arrayObject = heap->createArray(AT_REFERENCE, arraySize);
const u4 arrayObject = args.heap->createArray(AT_REFERENCE, arraySize);

const Array* fieldsArray = heap->getArray(arrayObject);
const Array* fieldsArray = args.heap->getArray(arrayObject);

ClassInfo* fieldClass = VM->getClass("java/lang/reflect/Field", thread);
ClassInfo* fieldClass = args.vm->getClass("java/lang/reflect/Field", args.thread);

for (u4 currentField = 0; currentField < arraySize; ++currentField)
{
const u4 fieldObjectRef = heap->createObject(fieldClass, VM);
const Object* fieldObject = heap->getObject(fieldObjectRef);
const u4 fieldObjectRef = args.heap->createObject(fieldClass, args.vm);
const Object* fieldObject = args.heap->getObject(fieldObjectRef);
const FieldInfo* fieldInfo = classObject->classClassInfo->fields[currentField];

// Set the name field
FieldData* nameField = fieldObject->getField("name", "Ljava/lang/String;", heap);
FieldData* nameField = fieldObject->getField("name", "Ljava/lang/String;", args.heap);
std::string_view fieldName = classObject->classClassInfo->constantPool->getString(fieldInfo->nameIndex);
std::string_view fieldType = classObject->classClassInfo->constantPool->getString(fieldInfo->descriptorIndex);
const u4 fieldNameStringObjectRef = heap->createString(fieldName.data(), VM);
const u4 fieldNameStringObjectRef = args.heap->createString(fieldName.data(), args.vm);
nameField->data->data = fieldNameStringObjectRef;

// Set the slot field
FieldData* slotField = fieldObject->getField("slot", "I", heap);
FieldData* slotField = fieldObject->getField("slot", "I", args.heap);
slotField->data->data = currentField;

// Set the class field
FieldData* classField = fieldObject->getField("clazz", "Ljava/lang/Class;", heap);
FieldData* classField = fieldObject->getField("clazz", "Ljava/lang/Class;", args.heap);
classField->data->data = currentFrame->localVariables[0].data;

// Set the modifiers field
FieldData* modifiersField = fieldObject->getField("modifiers", "I", heap);
FieldData* modifiersField = fieldObject->getField("modifiers", "I", args.heap);
modifiersField->data->data = fieldInfo->accessFlags;

const FieldData* typeField = fieldObject->getField("type", "Ljava/lang/Class;", heap);
const u4 classObjectRef = heap->createClassObject(nullptr, VM, getTypeAsString(fieldType));
const FieldData* typeField = fieldObject->getField("type", "Ljava/lang/Class;", args.heap);
const u4 classObjectRef = args.heap->createClassObject(nullptr, args.vm, getTypeAsString(fieldType));
typeField->data->data = classObjectRef;


u4* array = reinterpret_cast<u4*>(fieldsArray->data);
array[currentField] = fieldObjectRef;
}

thread->returnVar(Variable{VariableType_REFERENCE, arrayObject});
args.thread->returnVar(Variable{VariableType_REFERENCE, arrayObject});
}

JCALL void lib_java_lang_Class_isPrimitive(NATIVE_ARGS)
JCALL void lib_java_lang_Class_isPrimitive(const NativeArgs& args)
{
const ClassObject* classObject = getThisClassObjectReference(thread, heap, VM);
const ClassObject* classObject = getThisClassObjectReference(args.thread, args.heap, args.vm);
u4 result = 0;

if (classObject->name == "int")
Expand Down Expand Up @@ -231,31 +231,31 @@ JCALL void lib_java_lang_Class_isPrimitive(NATIVE_ARGS)
result = 1u;
}

thread->returnVar(Variable{VariableType_INT, result});
args.thread->returnVar(Variable{VariableType_INT, result});
}

JCALL void lib_java_lang_Class_isAssignableFrom(NATIVE_ARGS)
JCALL void lib_java_lang_Class_isAssignableFrom(const NativeArgs& args)
{
const ClassObject* thisClassObject = getThisClassObjectReference(thread, heap, VM);
const ClassObject* thisClassObject = getThisClassObjectReference(args.thread, args.heap, args.vm);

const StackFrame* currentFrame = thread->m_currentFrame;
const StackFrame* currentFrame = args.thread->m_currentFrame;
const Variable var = currentFrame->localVariables[1];
VM->checkType(var, VariableType_REFERENCE, thread);
const ClassObject* clsClassObject = heap->getClassObject(var.data);
args.vm->checkType(var, VariableType_REFERENCE, args.thread);
const ClassObject* clsClassObject = args.heap->getClassObject(var.data);

// TODO: Add type conversion checking
const u4 result = VM->isSubclass(thread, thisClassObject->classClassInfo, clsClassObject->classClassInfo);
const u4 result = args.vm->isSubclass(args.thread, thisClassObject->classClassInfo, clsClassObject->classClassInfo);

thread->returnVar(Variable{VariableType_INT, result});
args.thread->returnVar(Variable{VariableType_INT, result});
}

JCALL void lib_java_lang_Class_isInterface(NATIVE_ARGS)
JCALL void lib_java_lang_Class_isInterface(const NativeArgs& args)
{
const ClassObject* classObject = heap->getClassObject(thread->m_currentFrame->localVariables[0].data);
const ClassObject* classObject = args.heap->getClassObject(args.thread->m_currentFrame->localVariables[0].data);
u4 result = 0;
if (classObject->classClassInfo->isInterface())
{
result = 1;
}
thread->returnVar(Variable{VariableType_INT, result});
args.thread->returnVar(Variable{VariableType_INT, result});
}
18 changes: 9 additions & 9 deletions src/Library/java/lang/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

#include "Library/NativeDefs.h"

JCALL void lib_java_lang_Class_registerNatives(NATIVE_ARGS);
JCALL void lib_java_lang_Class_getPrimitiveClass(NATIVE_ARGS);
JCALL void lib_java_lang_Class_desiredAssertionStatus0(NATIVE_ARGS);
JCALL void lib_java_lang_Class_getName0(NATIVE_ARGS);
JCALL void lib_java_lang_Class_forName0(NATIVE_ARGS);
JCALL void lib_java_lang_Class_getDeclaredFields0(NATIVE_ARGS);
JCALL void lib_java_lang_Class_isPrimitive(NATIVE_ARGS);
JCALL void lib_java_lang_Class_isAssignableFrom(NATIVE_ARGS);
JCALL void lib_java_lang_Class_isInterface(NATIVE_ARGS);
JCALL void lib_java_lang_Class_registerNatives(const NativeArgs& args);
JCALL void lib_java_lang_Class_getPrimitiveClass(const NativeArgs& args);
JCALL void lib_java_lang_Class_desiredAssertionStatus0(const NativeArgs& args);
JCALL void lib_java_lang_Class_getName0(const NativeArgs& args);
JCALL void lib_java_lang_Class_forName0(const NativeArgs& args);
JCALL void lib_java_lang_Class_getDeclaredFields0(const NativeArgs& args);
JCALL void lib_java_lang_Class_isPrimitive(const NativeArgs& args);
JCALL void lib_java_lang_Class_isAssignableFrom(const NativeArgs& args);
JCALL void lib_java_lang_Class_isInterface(const NativeArgs& args);
24 changes: 12 additions & 12 deletions src/Library/java/lang/Double.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@
#include "Double.h"


JCALL void lib_java_lang_Double_doubleToRawLongBits(NATIVE_ARGS)
JCALL void lib_java_lang_Double_doubleToRawLongBits(const NativeArgs& args)
{
const Variable highByte = thread->m_currentFrame->localVariables[1];
const Variable lowByte = thread->m_currentFrame->localVariables[0];
VM->checkType(highByte, VariableType_DOUBLE, thread);
VM->checkType(lowByte, VariableType_DOUBLE, thread);
const Variable highByte = args.thread->m_currentFrame->localVariables[1];
const Variable lowByte = args.thread->m_currentFrame->localVariables[0];
args.vm->checkType(highByte, VariableType_DOUBLE, args.thread);
args.vm->checkType(lowByte, VariableType_DOUBLE, args.thread);

thread->returnVar(
args.thread->returnVar(
Variable{VariableType_LONG, highByte.data},
Variable{VariableType_LONG, lowByte.data}
);
}

JCALL void lib_java_lang_Double_longBitsToDouble(NATIVE_ARGS) {
const Variable highByte = thread->m_currentFrame->localVariables[1];
const Variable lowByte = thread->m_currentFrame->localVariables[0];
VM->checkType(highByte, VariableType_LONG, thread);
VM->checkType(lowByte, VariableType_LONG, thread);
JCALL void lib_java_lang_Double_longBitsToDouble(const NativeArgs& args) {
const Variable highByte = args.thread->m_currentFrame->localVariables[1];
const Variable lowByte = args.thread->m_currentFrame->localVariables[0];
args.vm->checkType(highByte, VariableType_LONG, args.thread);
args.vm->checkType(lowByte, VariableType_LONG, args.thread);

thread->returnVar(
args.thread->returnVar(
Variable{VariableType_DOUBLE, highByte.data},
Variable{VariableType_DOUBLE, lowByte.data}
);
Expand Down
Loading

0 comments on commit e10c0d5

Please sign in to comment.