89 lines
1.7 KiB
C
89 lines
1.7 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "assert.h"
|
|
#include "class_resolver.h"
|
|
#include "memory_allocator.h"
|
|
|
|
enum tag_type {
|
|
TAG_TYPE_OBJECT = -30741,
|
|
TAG_TYPE_REF_ARRAY = 23240,
|
|
TAG_TYPE_PRIM_ARRAY = -5251,
|
|
};
|
|
|
|
struct tag {
|
|
int8_t mark;
|
|
int8_t _res;
|
|
int16_t type;
|
|
};
|
|
|
|
static_assert((sizeof (struct tag)) == 4);
|
|
|
|
struct objectref {
|
|
struct tag tag;
|
|
struct class_entry * class_entry;
|
|
union {
|
|
struct objectref * oref[0];
|
|
struct arrayref * aref[0];
|
|
uint32_t u32[0];
|
|
};
|
|
};
|
|
|
|
static_assert((sizeof (struct objectref)) == 8);
|
|
|
|
struct arrayref {
|
|
struct tag tag;
|
|
struct class_entry * class_entry;
|
|
int32_t length;
|
|
union {
|
|
// object array:
|
|
struct objectref * oref[0];
|
|
struct arrayref * aref[0];
|
|
void * ref[0];
|
|
// primitive array:
|
|
uint8_t u8[0];
|
|
uint16_t u16[0];
|
|
uint32_t u32[0];
|
|
uint64_t u64[0];
|
|
};
|
|
};
|
|
|
|
static_assert((sizeof (struct arrayref)) == 12);
|
|
|
|
enum ARRAY_TYPE {
|
|
T_BOOLEAN = 4, // 1 byte
|
|
T_CHAR = 5, // 2 bytes
|
|
T_FLOAT = 6, // 4 bytes
|
|
T_DOUBLE = 7, // 8 bytes
|
|
T_BYTE = 8, // 1 byte
|
|
T_SHORT = 9, // 2 bytes
|
|
T_INT = 10, // 4 bytes
|
|
T_LONG = 11, // 8 bytes
|
|
};
|
|
|
|
static inline int array_element_size(int atype)
|
|
{
|
|
switch (atype) {
|
|
case T_BOOLEAN: [[fallthrough]]; // 1 byte
|
|
case T_BYTE: // 1 byte
|
|
return 1;
|
|
break;
|
|
case T_CHAR: [[fallthrough]]; // 2 bytes
|
|
case T_SHORT: // 2 bytes
|
|
return 2;
|
|
break;
|
|
case T_FLOAT: [[fallthrough]]; // 4 bytes
|
|
case T_INT: // 4 bytes
|
|
return 4;
|
|
break;
|
|
case T_DOUBLE: [[fallthrough]]; // 8 bytes
|
|
case T_LONG: // 8 bytes
|
|
return 8;
|
|
break;
|
|
default:
|
|
assert(!"invalid atype");
|
|
break;
|
|
}
|
|
}
|