Skip to content

Commit

Permalink
Add very basic ClassObject creation
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandezseb committed Dec 24, 2023
1 parent 3076eb3 commit 9ff0db4
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/Library/Builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "java/io/FileDescriptor.h"
#include "java/io/FileOutputStream.h"
#include "java/lang/Class.h"
#include "java/lang/Object.h"
#include "java/lang/System.h"
#include "sun/misc/Unsafe.h"
Expand All @@ -11,6 +12,7 @@ void registerBuiltinRegisterNatives()
{
// java/lang package
registerNative("java/lang/Object/registerNatives", "()V", lib_java_lang_Object_registerNatives);
registerNative("java/lang/Class/registerNatives", "()V", lib_java_lang_Class_registerNatives);
registerNative("java/lang/System/registerNatives", "()V", lib_java_lang_System_registerNatives);
// java/io package
registerNative("java/io/FileOutputStream/initIDs", "()V", lib_java_io_FileOutputStream_initIDs);
Expand Down
2 changes: 2 additions & 0 deletions src/Library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ add_library(Library
Vigur/lang/System.cpp
java/lang/Object.h
java/lang/Object.cpp
java/lang/Class.h
java/lang/Class.cpp
java/lang/System.h
java/lang/System.cpp
java/io/FileOutputStream.h
Expand Down
5 changes: 5 additions & 0 deletions src/Library/java/lang/Class.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "Object.h"

JCALL void lib_java_lang_Class_registerNatives(JavaHeap* heap, VMThread* thread, VM* VM)
{
}
5 changes: 5 additions & 0 deletions src/Library/java/lang/Class.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "Library/NativeDefs.h"

JCALL void lib_java_lang_Class_registerNatives(JavaHeap* heap, VMThread* thread, VM* VM);
25 changes: 18 additions & 7 deletions src/VM/Instructions/ConstantInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,38 @@ void sipush(u1* args, u2 argsCount, i1 arg, JavaHeap* heap, VMThread* thread, VM

void loadConstant(const VMThread* thread, const u4 index, JavaHeap* heap, VM* VM)
{
const ConstantPoolItem* cpItem = thread->currentFrame->constantPool->constants[index-1];
const ConstantPoolItem* cpItem = thread->currentFrame->constantPool->constants[index - 1];
if (cpItem->getType() == CT_INTEGER)
{
const CPIntegerInfo* integerInfo = static_cast<const CPIntegerInfo*>(cpItem);
const Variable var{VariableType_INT, integerInfo->bytes};
thread->currentFrame->operands.push_back(var);
} else if (cpItem->getType() == CT_FLOAT)
}
else if (cpItem->getType() == CT_FLOAT)
{
const CPFloatInfo* floatInfo = static_cast<const CPFloatInfo*>(cpItem);
const Variable var{VariableType_FLOAT, floatInfo->bytes};
thread->currentFrame->operands.push_back(var);
}else if (cpItem->getType() == CT_STRING)
}
else if (cpItem->getType() == CT_STRING)
{
const CPStringInfo* stringInfo = static_cast<const CPStringInfo*>(cpItem);
const char* utf8String = thread->currentClass->constantPool->getString(stringInfo->stringIndex);
const uint32_t strObjectId = heap->createString(utf8String, VM);
const uint32_t strObjectId = heap->createString(utf8String, VM);
const Variable strVar{VariableType_REFERENCE, strObjectId};
thread->currentFrame->operands.push_back(strVar);
// TODO: If type is 7, check if a Class reference has already been created,
// TODO: if not, create this object and initialize the fields correctly
} else
}
else if (cpItem->getType() == CT_CLASS)
{
const CPClassInfo* classInfo = static_cast<const CPClassInfo*>(cpItem);
const char* className = thread->currentClass->constantPool->getString(classInfo->nameIndex);
ClassInfo* targetClassInfo = VM->getClass(className, const_cast<VMThread*>(thread));
const u4 classObjectRef = heap->createClassObject(heap->getClassByName("java/lang/Class"), VM, targetClassInfo);
const ClassObject * classObject = heap->getClassObject(classObjectRef);
const Variable classObjectVar{VariableType_REFERENCE, classObjectRef};
thread->currentFrame->operands.push_back(classObjectVar);
}
else
{
char buffer[200];
snprintf(buffer, 200, "LDC not implemented yet for type: %d", cpItem->getType());
Expand Down
90 changes: 89 additions & 1 deletion src/VM/JavaHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ uint32_t JavaHeap::createArray(ArrayType type, uint64_t size)

uint32_t JavaHeap::createObject(ClassInfo* classInfo, VM* VM)
{
// TODO: Fix undefined behavior with uninitialized memory in object
// We are NOT calling the constructor of the object here
Object* object = (Object*) Platform::allocateMemory(sizeof(Object), 0);
u2 fieldsCount = 0;
for (u2 currentField = 0; currentField < classInfo->fieldsCount; ++currentField)
Expand Down Expand Up @@ -99,6 +101,72 @@ uint32_t JavaHeap::createObject(ClassInfo* classInfo, VM* VM)
return objects.size()-1;
}

// TODO: De-duplicate code from createObject
uint32_t JavaHeap::createClassObject(ClassInfo* classInfo, VM* VM, ClassInfo* targetClassInfo)
{
// TODO: Fix undefined behavior with uninitialized memory in object
// We are NOT calling the constructor of the object here
ClassObject* object = (ClassObject*) Platform::allocateMemory(sizeof(ClassObject), 0);
u2 fieldsCount = 0;
for (u2 currentField = 0; currentField < classInfo->fieldsCount; ++currentField)
{
FieldInfo* fieldInfo = classInfo->fields[currentField];
if (!fieldInfo->isStatic())
{
++fieldsCount;
}
}

object->classInfo = classInfo;
object->type = CLASSOBJECT;
object->fields = 0;
if (fieldsCount > 0)
{
object->fields = (FieldData*) Platform::allocateMemory(sizeof(FieldData) * fieldsCount, 0);
}
object->fieldsCount = fieldsCount;
object->superClassObject = 0;
object->targetClassInfo = targetClassInfo;

fieldsCount = 0;
for (u2 currentField = 0; currentField < classInfo->fieldsCount; ++currentField)
{
FieldInfo* fieldInfo = classInfo->fields[currentField];
if (!fieldInfo->isStatic())
{
FieldData data = {};
data.descriptorIndex = fieldInfo->descriptorIndex;
data.nameIndex = fieldInfo->nameIndex;
const char* descriptorText = classInfo->constantPool->getString(fieldInfo->descriptorIndex);
std::vector<Variable> vars = VM->createVariableForDescriptor(descriptorText);
Variable* varsAllocated = (Variable*) Platform::allocateMemory(sizeof(Variable) * vars.size(), 0);
for (u1 currentVar = 0; currentVar < vars.size(); ++currentVar)
{
varsAllocated[currentVar] = vars[currentVar];
}
data.dataSize = vars.size();
data.data = varsAllocated;
object->fields[fieldsCount++] = data;
}
}

// Check if we are not in java/lang/Object, because that class doesn't have a superClas
if (classInfo->superClass != 0)
{
const char* superClassName = classInfo->constantPool->getString(classInfo->constantPool->getClassInfo(classInfo->superClass)->nameIndex);
if (strcmp(superClassName, "java/lang/Object") != 0)
{
ClassInfo* superClass = getClassByName(superClassName);
u4 superClassObject = createObject(superClass, VM);
object->superClassObject = superClassObject;
}
}

objects.push_back(object);
return objects.size()-1;
}


uint32_t JavaHeap::createString(const char* utf8String, VM* VM) {
const u4 existingString = getString(utf8String);
if (existingString != 0) {
Expand Down Expand Up @@ -129,7 +197,7 @@ Object* JavaHeap::getObject(const uint32_t id) const
Reference* ref = objects[id];
if (ref->type == OBJECT)
{
return (Object*) objects[id];
return static_cast<Object*>(objects[id]);
} else
{
fprintf(stderr, "Error: Array instead of Object\n");
Expand All @@ -138,6 +206,26 @@ Object* JavaHeap::getObject(const uint32_t id) const
return nullptr;
}

ClassObject* JavaHeap::getClassObject(uint32_t id) const
{
if (id == 0)
{
// Nullpointer
fprintf(stderr, "Error: Null pointer exception!\n");
Platform::exitProgram(-1);
}
Reference* ref = objects[id];
if (ref->type == CLASSOBJECT)
{
return static_cast<ClassObject*>(objects[id]);
} else
{
fprintf(stderr, "Error: Array or Object instead of ClassObject\n");
Platform::exitProgram(-22);
}
return nullptr;
}

Object* JavaHeap::getChildObject(uint32_t id, ClassInfo* classInfo)
{
Object* o = getObject(id);
Expand Down
21 changes: 13 additions & 8 deletions src/VM/JavaHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ class VM;
class JavaHeap;

enum ReferenceType : char {
OBJECT, ARRAY
OBJECT, ARRAY, CLASSOBJECT
};

class Object;
class Array;

class Reference {
public:
explicit Reference(ReferenceType type) { this->type = type; };
ReferenceType type;

Array* getArray() {
Expand Down Expand Up @@ -55,15 +54,19 @@ class FieldData {

class Object : public Reference {
public:
Object() : Reference(OBJECT) {
};
FieldData* fields;
uint16_t fieldsCount;
ClassInfo* classInfo;
u4 superClassObject;
FieldData* fields{nullptr};
uint16_t fieldsCount{0};
ClassInfo* classInfo{nullptr};
u4 superClassObject{0};
FieldData* getField(const char* name, const char* descriptor, JavaHeap* heap) const;
};

class ClassObject : public Object
{
public:
ClassInfo* targetClassInfo{nullptr};
};

class Array : public Reference {
public:
Array() : Reference(ARRAY), arrayType(AT_UNDEFINED), length(0l), data(nullptr) {
Expand Down Expand Up @@ -93,9 +96,11 @@ class JavaHeap {
*/
uint32_t createArray(ArrayType type, uint64_t size);
uint32_t createObject(ClassInfo* classInfo, VM* VM);
uint32_t createClassObject(ClassInfo* classInfo, VM* VM, ClassInfo* targetClassInfo);
uint32_t createString(const char* utf8String, VM* VM);

[[nodiscard]] Object* getObject(uint32_t id) const;
[[nodiscard]] ClassObject* getClassObject(uint32_t id) const;
[[nodiscard]] Object* getChildObject(uint32_t id, ClassInfo* classInfo);
[[nodiscard]] Array* getArray(u4 id) const;
[[nodiscard]] u4 getString(const char* utf8String) const;
Expand Down
1 change: 1 addition & 0 deletions src/VM/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ void VM::start()
getClass("java/lang/OutOfMemoryError", &thread);
getClass("java/lang/VirtualMachineError", &thread);
getClass("java/lang/Object", &thread);
getClass("java/lang/Class", &thread);
getClass("java/lang/String", &thread);
getClass("java/lang/System", &thread);
getClass("Vigur/lang/System", &thread);
Expand Down

0 comments on commit 9ff0db4

Please sign in to comment.