/*  structs.c -- runtime structures for Toba  */

#include <string.h>
#include <stddef.h>
#include <assert.h>

#include "toba.h"
#include "runtime.h"

#include "java_lang_Class.h"
#include "java_lang_Object.h"
#include "java_lang_String.h"



/*  character arrays used by class label strings  */

static CARRAY(7) c_boolean = {&acl_char, 0, 7, 0, {'b','o','o','l','e','a','n'}};
static CARRAY(4) c_char    = {&acl_char, 0, 4, 0, {'c','h','a','r'}};
static CARRAY(4) c_byte    = {&acl_char, 0, 4, 0, {'b','y','t','e'}};
static CARRAY(5) c_short   = {&acl_char, 0, 5, 0, {'s','h','o','r','t'}};
static CARRAY(3) c_int     = {&acl_char, 0, 3, 0, {'i','n','t'}};
static CARRAY(4) c_long    = {&acl_char, 0, 4, 0, {'l','o','n','g'}};
static CARRAY(5) c_float   = {&acl_char, 0, 5, 0, {'f','l','o','a','t'}};
static CARRAY(6) c_double  = {&acl_char, 0, 6, 0, {'d','o','u','b','l','e'}};

static CARRAY(2) c_aboolean = {&acl_char, 0, 2, 0, {'[','Z'}};
static CARRAY(2) c_achar    = {&acl_char, 0, 2, 0, {'[','C'}};
static CARRAY(2) c_abyte    = {&acl_char, 0, 2, 0, {'[','B'}};
static CARRAY(2) c_ashort   = {&acl_char, 0, 2, 0, {'[','S'}};
static CARRAY(2) c_aint     = {&acl_char, 0, 2, 0, {'[','I'}};
static CARRAY(2) c_along    = {&acl_char, 0, 2, 0, {'[','J'}};
static CARRAY(2) c_afloat   = {&acl_char, 0, 2, 0, {'[','F'}};
static CARRAY(2) c_adouble  = {&acl_char, 0, 2, 0, {'[','D'}};



/*  class label strings  */

#define STRING(label,n,carray) \
   struct in_java_lang_String label = { &cl_java_lang_String, 0, &carray, 0, n }

static STRING(s_boolean,7,c_boolean);
static STRING(s_char,4,c_char);
static STRING(s_byte,4,c_byte);
static STRING(s_short,5,c_short);
static STRING(s_int,3,c_int);
static STRING(s_long,4,c_long);
static STRING(s_float,5,c_float);
static STRING(s_double,6,c_double);

static STRING(s_aboolean,2,c_aboolean);
static STRING(s_achar,2,c_achar);
static STRING(s_abyte,2,c_abyte);
static STRING(s_ashort,2,c_ashort);
static STRING(s_aint,2,c_aint);
static STRING(s_along,2,c_along);
static STRING(s_afloat,2,c_afloat);
static STRING(s_adouble,2,c_adouble);



/*  class structs for primitives and their arrays  */

static Class objptr = &cl_java_lang_Object.C;

#define CLASS(type,elemsize) \
struct class cl_##type = { 0, IS_PRIMITIVE, &s_##type, \
    { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, &acl_##type.C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; \
struct cl_java_lang_Object acl_##type = { 0, IS_ARRAY, &s_a##type, \
    { &cl_java_lang_Class.C, 0 }, elemsize, 0, 0, 0, 0, 1, &objptr, 0, 0, 0, \
    0, 0, 0, 0, 0, &cl_##type, 0, 0, 0, OBJ_INIT, OBJ_FINI, 0, 0, 0, 0, 0 };

CLASS(boolean,1)
CLASS(char,2)
CLASS(byte,1)
CLASS(short,2)
CLASS(int,4)
CLASS(long,8)
CLASS(float,4)
CLASS(double,8)



/*  runtime initialization  */

void initstructs(void)
{
    /* sanity checks */
    assert(sizeof(Boolean) == 1);
    assert(sizeof(Char) == 2);
    assert(sizeof(Byte) == 1);
    assert(sizeof(Short) == 2);
    assert(sizeof(Int) == 4);
    assert(sizeof(Long) == 8);

    /* all arrays should be laid out identically */
    assert(offsetof(struct aarray,data[0]) == offsetof(struct barray,data[0]) &&
           offsetof(struct barray,data[0]) == offsetof(struct carray,data[0]) &&
           offsetof(struct carray,data[0]) == offsetof(struct darray,data[0]) &&
           offsetof(struct darray,data[0]) == offsetof(struct farray,data[0]) &&
           offsetof(struct farray,data[0]) == offsetof(struct iarray,data[0]) &&
           offsetof(struct iarray,data[0]) == offsetof(struct larray,data[0]) &&
           offsetof(struct larray,data[0]) == offsetof(struct sarray,data[0]));
    
    memcpy(&acl_boolean.M, &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_char.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_byte.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_short.M,   &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_int.M,     &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_long.M,    &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_float.M,   &OBJ_METHODS, sizeof(OBJ_METHODS));
    memcpy(&acl_double.M,  &OBJ_METHODS, sizeof(OBJ_METHODS));

    acl_boolean.C.nimethods = cl_java_lang_Object.C.nimethods;
    acl_char.C.nimethods    = cl_java_lang_Object.C.nimethods;
    acl_byte.C.nimethods    = cl_java_lang_Object.C.nimethods;
    acl_short.C.nimethods   = cl_java_lang_Object.C.nimethods;
    acl_int.C.nimethods     = cl_java_lang_Object.C.nimethods;
    acl_long.C.nimethods    = cl_java_lang_Object.C.nimethods;
    acl_float.C.nimethods   = cl_java_lang_Object.C.nimethods;
    acl_double.C.nimethods  = cl_java_lang_Object.C.nimethods;

    acl_boolean.C.nsmethods = cl_java_lang_Object.C.nsmethods;
    acl_boolean.C.smethods  = cl_java_lang_Object.C.smethods;
    acl_char.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
    acl_char.C.smethods     = cl_java_lang_Object.C.smethods;
    acl_byte.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
    acl_byte.C.smethods     = cl_java_lang_Object.C.smethods;
    acl_short.C.nsmethods   = cl_java_lang_Object.C.nsmethods;
    acl_short.C.smethods    = cl_java_lang_Object.C.smethods;
    acl_int.C.nsmethods     = cl_java_lang_Object.C.nsmethods;
    acl_int.C.smethods      = cl_java_lang_Object.C.smethods;
    acl_long.C.nsmethods    = cl_java_lang_Object.C.nsmethods;
    acl_long.C.smethods     = cl_java_lang_Object.C.smethods;
    acl_float.C.nsmethods   = cl_java_lang_Object.C.nsmethods;
    acl_float.C.smethods    = cl_java_lang_Object.C.smethods;
    acl_double.C.nsmethods  = cl_java_lang_Object.C.nsmethods;
    acl_double.C.smethods   = cl_java_lang_Object.C.smethods;

    acl_boolean.C.nivars    = cl_java_lang_Object.C.nivars;
    acl_boolean.C.ivars     = cl_java_lang_Object.C.ivars;
    acl_char.C.nivars       = cl_java_lang_Object.C.nivars;
    acl_char.C.ivars        = cl_java_lang_Object.C.ivars;
    acl_byte.C.nivars       = cl_java_lang_Object.C.nivars;
    acl_byte.C.ivars        = cl_java_lang_Object.C.ivars;
    acl_short.C.nivars      = cl_java_lang_Object.C.nivars;
    acl_short.C.ivars       = cl_java_lang_Object.C.ivars;
    acl_int.C.nivars        = cl_java_lang_Object.C.nivars;
    acl_int.C.ivars         = cl_java_lang_Object.C.ivars;
    acl_long.C.nivars       = cl_java_lang_Object.C.nivars;
    acl_long.C.ivars        = cl_java_lang_Object.C.ivars;
    acl_float.C.nivars      = cl_java_lang_Object.C.nivars;
    acl_float.C.ivars       = cl_java_lang_Object.C.ivars;
    acl_double.C.nivars     = cl_java_lang_Object.C.nivars;
    acl_double.C.ivars      = cl_java_lang_Object.C.ivars;

    acl_boolean.C.ncvars    = cl_java_lang_Object.C.ncvars;
    acl_boolean.C.cvars     = cl_java_lang_Object.C.cvars;
    acl_char.C.ncvars       = cl_java_lang_Object.C.ncvars;
    acl_char.C.cvars        = cl_java_lang_Object.C.cvars;
    acl_byte.C.ncvars       = cl_java_lang_Object.C.ncvars;
    acl_byte.C.cvars        = cl_java_lang_Object.C.cvars;
    acl_short.C.ncvars      = cl_java_lang_Object.C.ncvars;
    acl_short.C.cvars       = cl_java_lang_Object.C.cvars;
    acl_int.C.ncvars        = cl_java_lang_Object.C.ncvars;
    acl_int.C.cvars         = cl_java_lang_Object.C.cvars;
    acl_long.C.ncvars       = cl_java_lang_Object.C.ncvars;
    acl_long.C.cvars        = cl_java_lang_Object.C.cvars;
    acl_float.C.ncvars      = cl_java_lang_Object.C.ncvars;
    acl_float.C.cvars       = cl_java_lang_Object.C.cvars;
    acl_double.C.ncvars     = cl_java_lang_Object.C.ncvars;
    acl_double.C.cvars      = cl_java_lang_Object.C.cvars;

}
