Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,17 @@ typedef struct {

typedef struct basic_block basic_block_t;

/* Definition of a dynamic array structure for sources in src/globals.c
* size: Current number of elements in the array
* capacity: Number of elements that can be stored without resizing
* elements: Pointer to the array of characters
*/
typedef struct {
int size;
int capacity;
char *elements;
} source_t;

/* phase-2 IR definition */
struct ph2_ir {
opcode_t op;
Expand Down
76 changes: 67 additions & 9 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ int aliases_idx = 0;
constant_t *CONSTANTS;
int constants_idx = 0;

char *SOURCE;
int source_idx = 0;
source_t *SOURCE;

/* ELF sections */

Expand Down Expand Up @@ -837,6 +836,62 @@ void add_insn(block_t *block,
bb->insn_list.tail = n;
}

source_t *create_source(int init_capacity)
{
source_t *array = malloc(sizeof(source_t));
if (!array)
return NULL;

array->size = 0;
array->capacity = init_capacity;
array->elements = malloc(array->capacity * sizeof(char));
if (!array->elements) {
free(array);
return NULL;
}

return array;
}

bool source_expand(source_t *src)
{
if (src->size < src->capacity)
return true;

src->capacity <<= 1;
char *new_arr = malloc(src->capacity * sizeof(char));

if (!new_arr)
return false;

memcpy(new_arr, src->elements, src->size * sizeof(char));

free(src->elements);
src->elements = new_arr;

return true;
}

bool source_push(source_t *src, char value)
{
if (!source_expand(src))
return false;

src->elements[src->size] = value;
src->size++;

return true;
}

void source_release(source_t *src)
{
if (!src)
return;

free(src->elements);
free(src);
}

/* This routine is required because the global variable initializations are
* not supported now.
*/
Expand All @@ -855,7 +910,7 @@ void global_init()
BB_ARENA = arena_init(DEFAULT_ARENA_SIZE);
PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *));
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
SOURCE = malloc(MAX_SOURCE);
SOURCE = create_source(MAX_SOURCE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking of choosing an appropriate power of 2 for MAX_SOURCE. perhaps 2^18 (262144 B, or 256 KiB) or 2^19 (524288 B, or 512 KiB) would be better?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, we do need scientific ways to calculate.

ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));

Expand Down Expand Up @@ -887,7 +942,7 @@ void global_release()
arena_free(BB_ARENA);
free(PH2_IR_FLATTEN);
free(LABEL_LUT);
free(SOURCE);
source_release(SOURCE);
free(ALIASES);
free(CONSTANTS);

Expand All @@ -907,18 +962,20 @@ void error(char *msg)
int offset, start_idx, i = 0;
char diagnostic[512 /* MAX_LINE_LEN * 2 */];

for (offset = source_idx; offset >= 0 && SOURCE[offset] != '\n'; offset--)
for (offset = SOURCE->size; offset >= 0 && SOURCE->elements[offset] != '\n';
offset--)
;

start_idx = offset + 1;

for (offset = 0; offset < MAX_SOURCE && SOURCE[start_idx + offset] != '\n';
for (offset = 0;
offset < MAX_SOURCE && SOURCE->elements[start_idx + offset] != '\n';
offset++) {
diagnostic[i++] = SOURCE[start_idx + offset];
diagnostic[i++] = SOURCE->elements[start_idx + offset];
}
diagnostic[i++] = '\n';

for (offset = start_idx; offset < source_idx; offset++) {
for (offset = start_idx; offset < SOURCE->size; offset++) {
diagnostic[i++] = ' ';
}

Expand All @@ -927,7 +984,8 @@ void error(char *msg)
/* TODO: figure out the corresponding C source file path and report line
* number.
*/
printf("Error %s at source location %d\n%s\n", msg, source_idx, diagnostic);
printf("Error %s at source location %d\n%s\n", msg, SOURCE->size,
diagnostic);
abort();
}

Expand Down
16 changes: 9 additions & 7 deletions src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,14 @@ void skip_whitespace()
{
while (true) {
if (is_linebreak(next_char)) {
source_idx += 2;
next_char = SOURCE[source_idx];
SOURCE->size += 2;
next_char = SOURCE->elements[SOURCE->size];
continue;
}
if (is_whitespace(next_char) ||
(skip_newline && is_newline(next_char))) {
next_char = SOURCE[++source_idx];
SOURCE->size++;
next_char = SOURCE->elements[SOURCE->size];
continue;
}
break;
Expand All @@ -173,15 +174,16 @@ void skip_whitespace()

char read_char(bool is_skip_space)
{
next_char = SOURCE[++source_idx];
SOURCE->size++;
next_char = SOURCE->elements[SOURCE->size];
if (is_skip_space)
skip_whitespace();
return next_char;
}

char peek_char(int offset)
{
return SOURCE[source_idx + offset];
return SOURCE->elements[SOURCE->size + offset];
}

/* Lex next token and returns its token type. Parameter 'aliasing' is used for
Expand Down Expand Up @@ -601,8 +603,8 @@ token_t lex_token_internal(bool aliasing)
*/
if (next_char == '\n') {
if (macro_return_idx) {
source_idx = macro_return_idx;
next_char = SOURCE[source_idx];
SOURCE->size = macro_return_idx;
next_char = SOURCE->elements[SOURCE->size];
} else
next_char = read_char(true);
return lex_token_internal(aliasing);
Expand Down
56 changes: 28 additions & 28 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ bool read_preproc_directive()
if (lex_accept(T_elipsis))
macro->is_variadic = true;

macro->start_source_idx = source_idx;
macro->start_source_idx = SOURCE->size;
skip_macro_body();
} else {
/* Empty alias, may be dummy alias serves as include guard */
Expand Down Expand Up @@ -891,8 +891,8 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
macro_t *mac = find_macro(token);

if (!strcmp(token, "__VA_ARGS__")) {
/* 'source_idx' has pointed at the character after __VA_ARGS__ */
int remainder, t = source_idx;
/* 'size' has pointed at the character after __VA_ARGS__ */
int remainder, t = SOURCE->size;
macro_t *macro = parent->macro;

if (!macro)
Expand All @@ -902,13 +902,13 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)

remainder = macro->num_params - macro->num_param_defs;
for (int i = 0; i < remainder; i++) {
source_idx = macro->params[macro->num_params - remainder + i];
next_char = SOURCE[source_idx];
SOURCE->size = macro->params[macro->num_params - remainder + i];
next_char = SOURCE->elements[SOURCE->size];
next_token = lex_token();
read_expr(parent, bb);
}
source_idx = t;
next_char = SOURCE[source_idx];
SOURCE->size = t;
next_char = SOURCE->elements[SOURCE->size];
next_token = lex_token();
} else if (mac) {
if (parent->macro)
Expand All @@ -918,18 +918,18 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
mac->num_params = 0;
lex_expect(T_identifier);

/* 'source_idx' has pointed at the first parameter */
/* 'size' has pointed at the first parameter */
while (!lex_peek(T_close_bracket, NULL)) {
mac->params[mac->num_params++] = source_idx;
mac->params[mac->num_params++] = SOURCE->size;
do {
next_token = lex_token();
} while (next_token != T_comma &&
next_token != T_close_bracket);
}
/* move 'source_idx' to the macro body */
macro_return_idx = source_idx;
source_idx = mac->start_source_idx;
next_char = SOURCE[source_idx];
/* move 'size' to the macro body */
macro_return_idx = SOURCE->size;
SOURCE->size = mac->start_source_idx;
next_char = SOURCE->elements[SOURCE->size];
lex_expect(T_close_bracket);

skip_newline = 0;
Expand All @@ -941,13 +941,13 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
macro_return_idx = 0;
} else if (macro_param_idx) {
/* "expand" the argument from where it comes from */
int t = source_idx;
source_idx = macro_param_idx;
next_char = SOURCE[source_idx];
int t = SOURCE->size;
SOURCE->size = macro_param_idx;
next_char = SOURCE->elements[SOURCE->size];
next_token = lex_token();
read_expr(parent, bb);
source_idx = t;
next_char = SOURCE[source_idx];
SOURCE->size = t;
next_char = SOURCE->elements[SOURCE->size];
next_token = lex_token();
} else if (con) {
ph1_ir = add_ph1_ir(OP_load_constant);
Expand Down Expand Up @@ -3075,17 +3075,17 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
mac->num_params = 0;
lex_expect(T_identifier);

/* 'source_idx' has pointed at the first parameter */
/* 'size' has pointed at the first parameter */
while (!lex_peek(T_close_bracket, NULL)) {
mac->params[mac->num_params++] = source_idx;
mac->params[mac->num_params++] = SOURCE->size;
do {
next_token = lex_token();
} while (next_token != T_comma && next_token != T_close_bracket);
}
/* move 'source_idx' to the macro body */
macro_return_idx = source_idx;
source_idx = mac->start_source_idx;
next_char = SOURCE[source_idx];
/* move 'size' to the macro body */
macro_return_idx = SOURCE->size;
SOURCE->size = mac->start_source_idx;
next_char = SOURCE->elements[SOURCE->size];
lex_expect(T_close_bracket);

skip_newline = 0;
Expand Down Expand Up @@ -3377,8 +3377,8 @@ void parse_internal()
GLOBAL_FUNC.fn->bbs = calloc(1, sizeof(basic_block_t));

/* lexer initialization */
source_idx = 0;
next_char = SOURCE[0];
SOURCE->size = 0;
next_char = SOURCE->elements[0];
lex_expect(T_start);

do {
Expand Down Expand Up @@ -3415,8 +3415,8 @@ void load_source_file(char *file)
snprintf(path + c + 1, inclusion_path_len, "%s", buffer + 10);
load_source_file(path);
} else {
strcpy(SOURCE + source_idx, buffer);
source_idx += strlen(buffer);
strcpy(SOURCE->elements + SOURCE->size, buffer);
SOURCE->size += strlen(buffer);
}
}
fclose(f);
Expand Down
2 changes: 1 addition & 1 deletion tools/inliner.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ int main(int argc, char *argv[])
*/
write_str("void __c(char *src) {\n");
write_str(" for (int i = 0; src[i]; i++)\n");
write_str(" SOURCE[source_idx++] = src[i];\n");
write_str(" source_push(SOURCE, src[i]);\n");
write_str("}\n");

write_str("void libc_generate() {\n");
Expand Down