#include <stdio.h>
#include <assert.h>
#include <stddef.h>
#include "toba.h"

#include "java_lang_ClassLoader.h"
#include "toba_runtime_ClassRT.h"
#include "toba_runtime_SystemClassLoader.h"
#include "toba_runtime_CodeGen.h"
#include "runtime.h"
#include "sthreads.h"

static void *longToAddress(Long l)
{
    return (void *)(long)l;
}
static Long addressToLong(void *v)
{
    return (Long)(long)v;
}

Int typeSpace_c_aeVFQ(Char c)
{
    initclass(&cl_toba_runtime_CodeGen.C);

    switch (c) {
	case 'B':             return sizeof(Byte);
	case 'C':             return sizeof(Char);
	case 'D':  case 'd':  return sizeof(Double);
	case 'F':  case 'f':  return sizeof(Float);
	case 'I':  case 'i':  return sizeof(Int);
	case 'J':  case 'l':  return sizeof(Long);
	case 'S':             return sizeof(Short);
	case 'Z':             return sizeof(Boolean);
        default:              return sizeof(Object);
    }
}

/* We align things to the boundary of their size. */
Int typeAlignment_c_fvz3O(Char c)
{
    initclass(&cl_toba_runtime_CodeGen.C);

    switch (c) {
	case 'B':             return sizeof(Byte);
	case 'C':             return sizeof(Char);
	case 'D':  case 'd':  return sizeof(Double);
	case 'F':  case 'f':  return sizeof(Float);
	case 'I':  case 'i':  return sizeof(Int);
	case 'J':  case 'l':  return sizeof(Long);
	case 'S':             return sizeof(Short);
	case 'Z':             return sizeof(Boolean);
        default:              return sizeof(Object);
    }
}

Int baseSize__BnvOB()
{
    initclass(&cl_toba_runtime_CodeGen.C);

    return sizeof(struct in_generic);
}

Int baseAlignment__TWb2J()
{
    initclass(&cl_toba_runtime_CodeGen.C);

    if (sizeof(Class) > sizeof(Monitor))
	return sizeof(Class);
    else
	return sizeof(Monitor);
}

Void
pokeByte_lb_hu2R9 (Long addr,
                   Byte v)
{
   * (Byte *) longToAddress (addr) = v;
   return;
}

Void
pokeShort_ls_cLN3R (Long addr,
                    Short v)
{
   * (Short *) longToAddress (addr) = v;
   return;
}

Void
pokeInt_li_ZDc1h (Long addr,
                  Int v)
{
   * (Int *) longToAddress (addr) = v;
   return;
}

void
pokeLong_ll_FO5Cd (Long addr,
                   Long v)
{
   * (Long *) longToAddress (addr) = v;
   return;
}

/* Convert from an object reference to the address of that object.  So much for
 * strong typing. */
Long
getNativeObjectAddr_O_HIiqz (Object or)
{
   return addressToLong (or);
}

/* These are requirements automatically generated from JITCodeGen.c
 * that must hold for generated code to be correct. */
void
verifyRequirements__RTwoi (void)
{
   int rv;
   int nerrs = 0;
   
   /* NB: At the time this is called, we have not yet completely initialized
    * the system.  In particular, the thread structure hasn't been set up
    * (we get here from:
    * start/real_start/loader_init/codegen_init/Initialize__ek3Oa
    *  and setting up mythread is the next thing on the list
    * ), so we can't throw an exception if these fail. */

   if (! (0 == (rv = offsetof (struct vt_generic, offset)))) {
      fprintf (stderr, "JIT requirement failed: 0 == offsetof (struct vt_generic, offset) (actual %d)\n", rv);
      ++nerrs;
   }
   if (! (128 == (rv = offsetof (struct class, ivars)))) {
      fprintf (stderr, "JIT requirement failed: 128 == offsetof (struct class, ivars) (actual %d)\n", rv);
      ++nerrs;
   }
   if (! (140 == (rv = offsetof (struct cl_generic, M)))) {
      fprintf (stderr, "JIT requirement failed: 140 == offsetof (struct cl_generic, M) (actual %d)\n", rv);
      ++nerrs;
   }
   if (! (32 == (rv = sizeof (struct mt_generic)))) {
      fprintf (stderr, "JIT requirement failed: 32 == sizeof (struct mt_generic) (actual %d)\n", rv);
      ++nerrs;
   }
   if (! (32 == (rv = sizeof (struct vt_generic)))) {
      fprintf (stderr, "JIT requirement failed: 32 == sizeof (struct vt_generic) (actual %d)\n", rv);
      ++nerrs;
   }
   if (! (4 == (rv = offsetof (struct mt_generic, f)))) {
      fprintf (stderr, "JIT requirement failed: 4 == offsetof (struct mt_generic, f) (actual %d)\n", rv);
      ++nerrs;
   }
   assert (0 == nerrs);
}
