//===------ ClasspathReflect.h - GNU classpath definitions of ----------------//
// java/lang/Class, java/lang/reflect/Field, java/lang/reflect/Method and ----//
// java/lang/reflect/Constructor as compiled by JnJVM. -----------------------//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef JNJVM_CLASSPATH_REFLECT_H
#define JNJVM_CLASSPATH_REFLECT_H

#include "MvmGC.h"

#include <JavaClass.h>
#include <JavaObject.h>

extern "C" jnjvm::JavaObject* internalFillInStackTrace(jnjvm::JavaObject*);

namespace jnjvm {

class JavaObjectClass : public JavaObject {
public:
  JavaObject* signers;
  JavaObject* pd;
  UserCommonClass* vmdata;
  JavaObject* constructor;

public:
  
  UserCommonClass* getClass() {
    return vmdata;
  }

  static void staticTracer(JavaObjectClass* obj) {
    mvm::Collector::markAndTrace(obj, &obj->pd);
    mvm::Collector::markAndTrace(obj, &obj->signers);
    mvm::Collector::markAndTrace(obj, &obj->constructor);
    if (obj->vmdata) {
      JavaObject** Obj = obj->vmdata->classLoader->getJavaClassLoaderPtr();
      if (*Obj) mvm::Collector::markAndTraceRoot(Obj);
    }
  }
};

class JavaObjectField : public JavaObject {
private:
  uint8 flag;
  JavaObjectClass* declaringClass;
  JavaObject* name;
  uint32 slot;

public:

  static void staticTracer(JavaObjectField* obj) {
    mvm::Collector::markAndTrace(obj, &obj->name);
    mvm::Collector::markAndTrace(obj, &obj->declaringClass);
  }

  JavaField* getInternalField() {
    return &(((UserClass*)declaringClass->vmdata)->virtualFields[slot]);
  }

  UserClass* getClass() {
    return declaringClass->vmdata->asClass();
  }

};

class JavaObjectMethod : public JavaObject {
private:
  uint8 flag;
  JavaObjectClass* declaringClass;
  JavaObject* name;
  uint32 slot;

public:
  
  static void staticTracer(JavaObjectMethod* obj) {
    mvm::Collector::markAndTrace(obj, &obj->name);
    mvm::Collector::markAndTrace(obj, &obj->declaringClass);
  }
  
  JavaMethod* getInternalMethod() {
    return &(((UserClass*)declaringClass->vmdata)->virtualMethods[slot]);
  }
  
  UserClass* getClass() {
    return declaringClass->vmdata->asClass();
  }

};

class JavaObjectConstructor : public JavaObject {
private:
  uint8 flag;
  JavaObjectClass* clazz;
  uint32 slot;

public:
  static void staticTracer(JavaObjectConstructor* obj) {
    mvm::Collector::markAndTrace(obj, &obj->clazz);
  }
  
  JavaMethod* getInternalMethod() {
    return &(((UserClass*)clazz->vmdata)->virtualMethods[slot]);
  }
  
  UserClass* getClass() {
    return clazz->vmdata->asClass();
  }

};

class JavaObjectVMThread : public JavaObject {
private:
  JavaObject* thread;
  bool running;
  JavaObject* vmdata;

public:
  static void staticDestructor(JavaObjectVMThread* obj) {
    mvm::Thread* th = (mvm::Thread*)obj->vmdata;
    delete th;
  }
  
  static void staticTracer(JavaObjectVMThread* obj) {
    mvm::Collector::markAndTrace(obj, &obj->thread);
  }

};


class JavaObjectThrowable : public JavaObject {
private:
  JavaObject* detailedMessage;
  JavaObject* cause;
  JavaObject* stackTrace;
  JavaObject* vmState;

public:

  void setDetailedMessage(JavaObject* obj) {
    detailedMessage = obj;
  }

  void fillInStackTrace() {
    cause = this;
    vmState = internalFillInStackTrace(this);
    stackTrace = 0;
  }
};

class JavaObjectReference : public JavaObject {
private:
  JavaObject* referent;
  JavaObject* queue;
  JavaObject* nextOnQueue;

public:
  void init(JavaObject* r, JavaObject* q) {
    referent = r;
    queue = q;
  }

  JavaObject** getReferentPtr() { return &referent; }
  void setReferent(JavaObject* r) { referent = r; }
  
  static void staticTracer(JavaObjectReference* obj) {
    mvm::Collector::markAndTrace(obj, &obj->queue);
    mvm::Collector::markAndTrace(obj, &obj->nextOnQueue);
  }
};

}

#endif
