blob: fde1fb2fb3e0de85c9f797b7df959c22b2b62753 [file] [log] [blame]
//===----------- JavaThread.h - Java thread description -------------------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef JNJVM_JAVA_THREAD_H
#define JNJVM_JAVA_THREAD_H
#include <setjmp.h>
#include "mvm/Object.h"
#include "mvm/Threads/Cond.h"
#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
#include "JavaObject.h"
extern "C" void* __cxa_allocate_exception(unsigned);
extern "C" void __cxa_throw(void*, void*, void*);
namespace jnjvm {
class Class;
class JavaObject;
class Jnjvm;
class JavaThread : public mvm::Thread {
public:
static VirtualTable *VT;
JavaObject* javaThread;
Jnjvm* isolate;
mvm::Lock* lock;
mvm::Cond* varcond;
JavaObject* pendingException;
void* internalPendingException;
uint32 interruptFlag;
uint32 state;
std::vector<jmp_buf*> sjlj_buffers;
static const unsigned int StateRunning;
static const unsigned int StateWaiting;
static const unsigned int StateInterrupted;
virtual void print(mvm::PrintBuffer *buf) const;
virtual void TRACER;
~JavaThread();
JavaThread();
void initialise(JavaObject* thread, Jnjvm* isolate) {
this->javaThread = thread;
this->isolate = isolate;
this->lock = mvm::Lock::allocNormal();
this->varcond = mvm::Cond::allocCond();
this->interruptFlag = 0;
this->state = StateRunning;
this->pendingException = 0;
}
static JavaThread* get() {
return (JavaThread*)mvm::Thread::get();
}
static JavaObject* currentThread() {
JavaThread* result = get();
if (result != 0)
return result->javaThread;
else
return 0;
}
static void* getException() {
return (void*)
((char*)JavaThread::get()->internalPendingException - 8 * sizeof(void*));
}
static void throwException(JavaObject* obj) {
JavaThread* th = JavaThread::get();
assert(th->pendingException == 0 && "pending exception already there?");
th->pendingException = obj;
void* exc = __cxa_allocate_exception(0);
th->internalPendingException = exc;
__cxa_throw(exc, 0, 0);
}
static void throwPendingException() {
JavaThread* th = JavaThread::get();
assert(th->pendingException);
void* exc = __cxa_allocate_exception(0);
th->internalPendingException = exc;
__cxa_throw(exc, 0, 0);
}
static void clearException() {
JavaThread* th = JavaThread::get();
th->pendingException = 0;
th->internalPendingException = 0;
}
static bool compareException(UserClass* cl) {
JavaObject* pe = JavaThread::get()->pendingException;
assert(pe && "no pending exception?");
bool val = pe->classOf->subclassOf(cl);
return val;
}
static JavaObject* getJavaException() {
return JavaThread::get()->pendingException;
}
void returnFromNative() {
assert(sjlj_buffers.size());
#if defined(__MACH__)
longjmp((int*)sjlj_buffers.back(), 1);
#else
longjmp((__jmp_buf_tag*)sjlj_buffers.back(), 1);
#endif
}
};
} // end namespace jnjvm
#endif