#ifdef SERVICE

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Target/TargetJITInfo.h"

#include "../lib/ExecutionEngine/JIT/JIT.h"

#include "JavaThread.h"
#include "JavaJIT.h"
#include "Jnjvm.h"
#include "mvm/VirtualMachine.h"
#include "mvm/Threads/Cond.h"
#include "mvm/Threads/Locks.h"
#include "mvm/JIT.h"

#include "signal.h"

using namespace jnjvm;

#if defined(__MACH__) && !defined(__i386__)
#define FRAME_IP(fp) (fp[2])
#else
#define FRAME_IP(fp) (fp[1])
#endif



static void throwInlineStoppedBundleException() {
  void** addr = (void**)__builtin_frame_address(0);
  JavaThread* th = JavaThread::get();
  FRAME_IP(addr) = (void**)th->replacedEIPs[--th->eipIndex];
  th->throwException(th->ServiceException);
}

static void throwStoppedBundleException() {
  JavaThread* th = JavaThread::get();
  th->throwException(th->ServiceException);
}


static mvm::LockNormal lock;
static mvm::Cond cond;
static mvm::Thread* initiator = 0;
static bool Finished = true;

void terminationHandler(int) {
  void** addr = (void**)__builtin_frame_address(0);
  mvm::Thread* th = mvm::Thread::get();
  JnjvmClassLoader* stoppedBundle = 
    (JnjvmClassLoader*)(th->stoppingService->CU);
  void* baseSP = th->baseSP;
  bool inStack = false;
  while (addr && addr < baseSP && addr < addr[0]) {
    addr = (void**)addr[0];
    void** ptr = (void**)FRAME_IP(addr);
    JavaMethod* meth = JavaJIT::IPToJavaMethod(ptr);
    if (meth) {
      if (meth->classDef->classLoader == stoppedBundle) {
        inStack = true;
        JavaThread* th = JavaThread::get();
        th->replacedEIPs[th->eipIndex++] = FRAME_IP(addr);
        FRAME_IP(addr) = (void**)(uintptr_t)throwInlineStoppedBundleException;
      }
    }
  }

  // If the malicious bundle is in the stack, interrupt the thread.
  if (inStack) {
    JavaThread* th = JavaThread::get();
    th->lock.lock();
    th->interruptFlag = 1;

    // here we could also raise a signal for interrupting I/O
    if (th->state == JavaThread::StateWaiting) {
      th->state = JavaThread::StateInterrupted;
      th->varcond.signal();
    }
  
    th->lock.unlock();

  }

  if (mvm::Thread::get() != initiator) {
    lock.lock();
    while (!Finished)
      cond.wait(&lock);
    lock.unlock();
  }
}



void Jnjvm::stopService() {
  
  lock.lock();
  while (!Finished)
    cond.wait(&lock);

  Finished = false;
  lock.unlock();

  JnjvmClassLoader* bundle = (JnjvmClassLoader*)CU;
  bundle->getIsolate()->status = 1;
  mvm::Thread* th = mvm::Thread::get();
  th->stoppingService = this;
  initiator = th;
  for(mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
      cur = (mvm::Thread*)cur->next()) {
    mvm::VirtualMachine* executingVM = cur->MyVM;
    assert(executingVM && "Thread with no VM!");
    cur->stoppingService = this;
    uint32 res = cur->kill(SIGUSR1);
    assert(res == 0);

  }
  
  // I have to do it too!
  terminationHandler(0);
   
  llvm::TargetJITInfo& TJI = 
    ((llvm::JIT*)mvm::MvmModule::executionEngine)->getJITInfo();
  for (ClassMap::iterator i = bundle->getClasses()->map.begin(), 
       e = bundle->getClasses()->map.end(); i!= e; ++i) {
    Class* cl = i->second->asClass();

    if (cl) {
      for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
        if (cl->virtualMethods[i].code) {
          TJI.replaceMachineCodeForFunction(cl->virtualMethods[i].code,
                              (void*)(uintptr_t)throwStoppedBundleException);
        }
      }
    
      for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
        if (cl->staticMethods[i].code) {
          TJI.replaceMachineCodeForFunction(cl->staticMethods[i].code, 
                              (void*)(uintptr_t)throwStoppedBundleException);
        }
      }
    }
  }

  lock.lock();
  Finished = true;
  cond.broadcast();
  lock.unlock();
}

#endif
