Skip to content

Commit

Permalink
Switch to DataStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed Apr 4, 2024
1 parent 418dd48 commit a8832d1
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 187 deletions.
18 changes: 9 additions & 9 deletions src/util/gen_section.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

typedef struct {
uintptr_t start_address;
Buffer buf;
DataStorage ds;
} Section;

static Section sections[SECTION_COUNT];
Expand All @@ -28,7 +28,7 @@ void align_section_size(enum SectionType secno, size_t align) {

if (secno != SEC_BSS) {
Section *sec = &sections[secno];
buf_align(&sec->buf, align);
data_align(&sec->ds, align);
} else {
bss_size = ALIGN(bss_size, align);
}
Expand All @@ -37,7 +37,7 @@ void align_section_size(enum SectionType secno, size_t align) {
void add_section_data(enum SectionType secno, const void *data, size_t bytes) {
assert(secno != SEC_BSS);
Section *sec = &sections[secno];
buf_put(&sec->buf, data, bytes);
data_append(&sec->ds, data, bytes);
}

void add_code(const void *buf, size_t bytes) {
Expand All @@ -47,15 +47,15 @@ void add_code(const void *buf, size_t bytes) {
void fix_section_size(uintptr_t start_address) {
sections[SEC_CODE].start_address = start_address;
int rodata_align = MAX(section_aligns[SEC_RODATA], 1);
uintptr_t rodata_addr = ALIGN(start_address + sections[SEC_CODE].buf.size, rodata_align);
uintptr_t rodata_addr = ALIGN(start_address + sections[SEC_CODE].ds.len, rodata_align);
sections[SEC_RODATA].start_address = rodata_addr;

int data_align = MAX(section_aligns[SEC_DATA], 1);
sections[SEC_DATA].start_address =
ALIGN(sections[SEC_RODATA].start_address + sections[SEC_RODATA].buf.size, data_align);
ALIGN(sections[SEC_RODATA].start_address + sections[SEC_RODATA].ds.len, data_align);
int bss_align = MAX(section_aligns[SEC_BSS], 1);
sections[SEC_BSS].start_address =
sections[SEC_DATA].start_address + ALIGN(sections[SEC_DATA].buf.size, bss_align);
sections[SEC_DATA].start_address + ALIGN(sections[SEC_DATA].ds.len, bss_align);
}

void get_section_size(int section, size_t *psize, uintptr_t *ploadadr) {
Expand All @@ -67,7 +67,7 @@ void get_section_size(int section, size_t *psize, uintptr_t *ploadadr) {
const Section *sec = &sections[section];
if (ploadadr != NULL)
*ploadadr = sec->start_address;
*psize = sec->buf.size;
*psize = sec->ds.len;
}
break;
case SEC_BSS:
Expand All @@ -81,6 +81,6 @@ void get_section_size(int section, size_t *psize, uintptr_t *ploadadr) {

void output_section(FILE *fp, int section) {
Section *sec = &sections[section];
const void *data = sec->buf.data;
fwrite(data, sec->buf.size, 1, fp);
const void *buf = sec->ds.buf;
fwrite(buf, sec->ds.len, 1, fp);
}
164 changes: 130 additions & 34 deletions src/util/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,40 +330,6 @@ int64_t wrap_value(int64_t value, int size, bool is_unsigned) {

// Container

#define BUF_MIN (16 / 2)
#define BUF_ALIGN (16)

void buf_put(Buffer *buf, const void *data, size_t bytes) {
size_t size = buf->size;
size_t newsize = size + bytes;

if (newsize > buf->capa) {
size_t newcapa = ALIGN(MAX(newsize, BUF_MIN) * 2, BUF_ALIGN);
unsigned char *p = realloc(buf->data, newcapa);
if (p == NULL)
error("not enough memory");
buf->data = p;
buf->capa = newcapa;
}

memcpy(buf->data + size, data, bytes);
buf->size = newsize;
}

void buf_align(Buffer *buf, int align) {
size_t size = buf->size;
size_t aligned_size = ALIGN(size, align);
size_t add = aligned_size - size;
if (add <= 0)
return;

void *zero = calloc_or_die(add);
buf_put(buf, zero, add);
free(zero);

assert(buf->size == aligned_size);
}

Vector *new_vector(void) {
Vector *vec = malloc_or_die(sizeof(Vector));
vec_init(vec);
Expand Down Expand Up @@ -431,6 +397,136 @@ bool vec_contains(Vector *vec, void *elem) {
return false;
}

// DataStorage

void data_release(DataStorage *data) {
if (data->chunk_stack != NULL) {
free_vector(data->chunk_stack);
data->chunk_stack = NULL;
}
if (data->buf != NULL) {
free(data->buf);
data_init(data);
}
}

void data_init(DataStorage *data) {
data->chunk_stack = NULL;
data->buf = NULL;
data->capacity = 0;
data->len = 0;
}

void data_reserve(DataStorage *data, size_t capacity) {
if (data->capacity < capacity) {
const size_t MIN = 16;
size_t c = data->capacity << 1;
if (c > capacity)
capacity = c;
if (MIN > capacity)
capacity = MIN;
data->buf = realloc_or_die(data->buf, sizeof(*data->buf) * capacity);
data->capacity = capacity;
}
}

void data_insert(DataStorage *data, ssize_t _pos, const unsigned char *buf, size_t size) {
size_t pos = _pos == -1 ? data->len : (size_t)_pos;
assert(/* 0 <= pos && */ pos <= data->len);
size_t newlen = data->len + size;
data_reserve(data, newlen);
if (pos < data->len)
memmove(data->buf + pos + size, data->buf + pos, data->len - pos);
memcpy(data->buf + pos, buf, size);
data->len = newlen;
}

void data_append(DataStorage *data, const unsigned char *buf, size_t size) {
data_insert(data, -1, buf, size);
}

void data_push(DataStorage *data, unsigned char c) {
unsigned char buf[1] = {c};
data_insert(data, -1, buf, 1);
}

void data_align(DataStorage *data, int align) {
size_t len = data->len;
size_t aligned_len = ALIGN(len, align);
size_t add = aligned_len - len;
if (add <= 0)
return;

void *zero = calloc_or_die(add);
data_append(data, zero, add);
free(zero);

assert(data->len == aligned_len);
}

void data_concat(DataStorage *dst, DataStorage *src) {
data_insert(dst, -1, src->buf, src->len);
}

void data_leb128(DataStorage *data, ssize_t pos, int64_t val) {
unsigned char buf[12], *p = buf;
const int64_t MAX = 1 << 6;
for (;;) {
if (val < MAX && val >= -MAX) {
*p++ = val & 0x7f;
data_insert(data, pos, buf, p - buf);
return;
}
*p++ = (val & 0x7f) | 0x80;
val >>= 7;
}
}

void data_uleb128(DataStorage *data, ssize_t pos, uint64_t val) {
unsigned char buf[12], *p = buf;
const uint64_t MAX = 1 << 7;
for (;;) {
if (val < MAX) {
*p++ = val & 0x7f;
data_insert(data, pos, buf, p - buf);
return;
}
*p++ = (val & 0x7f) | 0x80;
val >>= 7;
}
}

void data_string(DataStorage *data, const void *str, size_t len) {
data_uleb128(data, -1, len);
data_append(data, (const unsigned char*)str, len);
}

void data_varuint32(DataStorage *data, ssize_t pos, uint64_t val) {
unsigned char buf[5], *p = buf;
for (int i = 0; i < 4; ++i) {
*p++ = (val & 0x7f) | 0x80;
val >>= 7;
}
*p++ = val & 0x7f;
data_insert(data, pos, buf, p - buf);
}

void data_open_chunk(DataStorage *data) {
Vector *stack = data->chunk_stack;
if (stack == NULL)
data->chunk_stack = stack = new_vector();
vec_push(stack, INT2VOIDP(data->len));
}

void data_close_chunk(DataStorage *data, ssize_t num) {
Vector *stack = data->chunk_stack;
assert(stack != NULL && stack->len > 0);
size_t pos = VOIDP2INT(vec_pop(stack));
if (num == (ssize_t)-1)
num = data->len - pos;
data_uleb128(data, pos, num);
}

// StringBuffer

typedef struct {
Expand Down
33 changes: 24 additions & 9 deletions src/util/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ int64_t wrap_value(int64_t value, int size, bool is_unsigned);

// Container

typedef struct Buffer {
unsigned char *data;
size_t capa;
size_t size;
} Buffer;

void buf_put(Buffer *buf, const void *data, size_t bytes);
void buf_align(Buffer *buf, int align);

typedef struct Vector {
void **data;
int capacity;
Expand All @@ -82,6 +73,30 @@ void vec_insert(Vector *vec, int pos, const void *elem);
void vec_remove_at(Vector *vec, int index);
bool vec_contains(Vector *vec, void *elem);

// DataStorage

typedef struct DataStorage {
Vector *chunk_stack;
unsigned char *buf;
size_t capacity;
size_t len;
} DataStorage;

void data_release(DataStorage *data);
void data_init(DataStorage *data);
void data_reserve(DataStorage *data, size_t capacity);
void data_insert(DataStorage *data, ssize_t pos, const unsigned char *buf, size_t size);
void data_append(DataStorage *data, const unsigned char *buf, size_t size);
void data_push(DataStorage *data, unsigned char c);
void data_align(DataStorage *data, int align);
void data_concat(DataStorage *dst, DataStorage *src);
void data_leb128(DataStorage *data, ssize_t pos, int64_t val);
void data_uleb128(DataStorage *data, ssize_t pos, uint64_t val);
void data_string(DataStorage *data, const void *str, size_t len);
void data_open_chunk(DataStorage *data);
void data_close_chunk(DataStorage *data, ssize_t num);
void data_varuint32(DataStorage *data, ssize_t pos, uint64_t val);

// StringBuffer

typedef struct StringBuffer {
Expand Down
21 changes: 0 additions & 21 deletions src/wcc/wcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,27 +145,6 @@ TagInfo *getsert_tag(const Name *name, int typeindex);

void write_wasm_header(FILE *ofp);

typedef struct DataStorage {
Vector *chunk_stack;
unsigned char *buf;
size_t capacity;
size_t len;
} DataStorage;

void data_release(DataStorage *data);
void data_init(DataStorage *data);
void data_reserve(DataStorage *data, size_t capacity);
void data_insert(DataStorage *data, ssize_t pos, const unsigned char *buf, size_t size);
void data_append(DataStorage *data, const unsigned char *buf, size_t size);
void data_push(DataStorage *data, unsigned char c);
void data_concat(DataStorage *dst, DataStorage *src);
void data_leb128(DataStorage *data, ssize_t pos, int64_t val);
void data_uleb128(DataStorage *data, ssize_t pos, uint64_t val);
void data_string(DataStorage *data, const void *str, size_t len);
void data_open_chunk(DataStorage *data);
void data_close_chunk(DataStorage *data, ssize_t num);
void data_varuint32(DataStorage *data, ssize_t pos, uint64_t val);

typedef struct FuncExtra {
Vector *funcall_results; // [0]=Expr*, [1]=VarInfo*
DataStorage *code;
Expand Down
Loading

0 comments on commit a8832d1

Please sign in to comment.