Skip to content

Commit 390a0b6

Browse files
Jim HsuChAoSUnItY
andcommitted
Replace char* SOURCE with dynamic array
This commit replace `SOURCE` (in `src/global.c`) with a dynamically allocated array instead of a static string. Including: - Replaced char* SOURCE with a dynamically allocated array using malloc and free. - Updated related logic accordingly. Co-authored-by: Kyle Lin <[email protected]>
1 parent a603970 commit 390a0b6

File tree

5 files changed

+112
-45
lines changed

5 files changed

+112
-45
lines changed

src/defs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ typedef struct {
270270

271271
typedef struct basic_block basic_block_t;
272272

273+
/* source dynamic array definition*/
274+
275+
typedef struct {
276+
int size;
277+
int capacity;
278+
char *elements;
279+
} source_t;
280+
273281
/* phase-2 IR definition */
274282
struct ph2_ir {
275283
opcode_t op;

src/globals.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ int aliases_idx = 0;
5656
constant_t *CONSTANTS;
5757
int constants_idx = 0;
5858

59-
char *SOURCE;
60-
int source_idx = 0;
59+
source_t *SOURCE;
6160

6261
/* ELF sections */
6362

@@ -837,6 +836,61 @@ void add_insn(block_t *block,
837836
bb->insn_list.tail = n;
838837
}
839838

839+
source_t *create_source(int init_capacity)
840+
{
841+
source_t *array = malloc(sizeof(source_t));
842+
if (!array)
843+
return NULL;
844+
845+
array->size = 0;
846+
array->capacity = init_capacity;
847+
array->elements = malloc(array->capacity * sizeof(char));
848+
if (!array->elements) {
849+
free(array);
850+
return NULL;
851+
}
852+
853+
return array;
854+
}
855+
856+
bool source_expand(source_t *self)
857+
{
858+
if (self->size < self->capacity)
859+
return true;
860+
861+
self->capacity <<= 1;
862+
char *new_arr = malloc(self->capacity * sizeof(char));
863+
864+
if (!new_arr)
865+
return false;
866+
867+
memcpy(new_arr, self->elements, self->size * sizeof(char));
868+
869+
free(self->elements);
870+
self->elements = new_arr;
871+
872+
return true;
873+
}
874+
875+
bool source_push(source_t *self, char value)
876+
{
877+
if (!source_expand(self))
878+
return false;
879+
880+
self->elements[self->size] = value;
881+
self->size++;
882+
883+
return true;
884+
}
885+
886+
void source_release(source_t *self)
887+
{
888+
if (self) {
889+
free(self->elements);
890+
free(self);
891+
}
892+
}
893+
840894
/* This routine is required because the global variable initializations are
841895
* not supported now.
842896
*/
@@ -855,7 +909,7 @@ void global_init()
855909
BB_ARENA = arena_init(DEFAULT_ARENA_SIZE);
856910
PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *));
857911
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
858-
SOURCE = malloc(MAX_SOURCE);
912+
SOURCE = create_source(MAX_SOURCE);
859913
ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
860914
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));
861915

@@ -887,7 +941,7 @@ void global_release()
887941
arena_free(BB_ARENA);
888942
free(PH2_IR_FLATTEN);
889943
free(LABEL_LUT);
890-
free(SOURCE);
944+
source_release(SOURCE);
891945
free(ALIASES);
892946
free(CONSTANTS);
893947

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

910-
for (offset = source_idx; offset >= 0 && SOURCE[offset] != '\n'; offset--)
964+
for (offset = SOURCE->size; offset >= 0 && SOURCE->elements[offset] != '\n';
965+
offset--)
911966
;
912967

913968
start_idx = offset + 1;
914969

915-
for (offset = 0; offset < MAX_SOURCE && SOURCE[start_idx + offset] != '\n';
970+
for (offset = 0;
971+
offset < MAX_SOURCE && SOURCE->elements[start_idx + offset] != '\n';
916972
offset++) {
917-
diagnostic[i++] = SOURCE[start_idx + offset];
973+
diagnostic[i++] = SOURCE->elements[start_idx + offset];
918974
}
919975
diagnostic[i++] = '\n';
920976

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

@@ -927,7 +983,8 @@ void error(char *msg)
927983
/* TODO: figure out the corresponding C source file path and report line
928984
* number.
929985
*/
930-
printf("Error %s at source location %d\n%s\n", msg, source_idx, diagnostic);
986+
printf("Error %s at source location %d\n%s\n", msg, SOURCE->size,
987+
diagnostic);
931988
abort();
932989
}
933990

src/lexer.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,14 @@ void skip_whitespace()
158158
{
159159
while (true) {
160160
if (is_linebreak(next_char)) {
161-
source_idx += 2;
162-
next_char = SOURCE[source_idx];
161+
SOURCE->size += 2;
162+
next_char = SOURCE->elements[SOURCE->size];
163163
continue;
164164
}
165165
if (is_whitespace(next_char) ||
166166
(skip_newline && is_newline(next_char))) {
167-
next_char = SOURCE[++source_idx];
167+
SOURCE->size++;
168+
next_char = SOURCE->elements[SOURCE->size];
168169
continue;
169170
}
170171
break;
@@ -173,15 +174,16 @@ void skip_whitespace()
173174

174175
char read_char(bool is_skip_space)
175176
{
176-
next_char = SOURCE[++source_idx];
177+
SOURCE->size++;
178+
next_char = SOURCE->elements[SOURCE->size];
177179
if (is_skip_space)
178180
skip_whitespace();
179181
return next_char;
180182
}
181183

182184
char peek_char(int offset)
183185
{
184-
return SOURCE[source_idx + offset];
186+
return SOURCE->elements[SOURCE->size + offset];
185187
}
186188

187189
/* Lex next token and returns its token type. Parameter 'aliasing' is used for
@@ -601,8 +603,8 @@ token_t lex_token_internal(bool aliasing)
601603
*/
602604
if (next_char == '\n') {
603605
if (macro_return_idx) {
604-
source_idx = macro_return_idx;
605-
next_char = SOURCE[source_idx];
606+
SOURCE->size = macro_return_idx;
607+
next_char = SOURCE->elements[SOURCE->size];
606608
} else
607609
next_char = read_char(true);
608610
return lex_token_internal(aliasing);

src/parser.c

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ bool read_preproc_directive()
408408
if (lex_accept(T_elipsis))
409409
macro->is_variadic = true;
410410

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

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

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

903903
remainder = macro->num_params - macro->num_param_defs;
904904
for (int i = 0; i < remainder; i++) {
905-
source_idx = macro->params[macro->num_params - remainder + i];
906-
next_char = SOURCE[source_idx];
905+
SOURCE->size = macro->params[macro->num_params - remainder + i];
906+
next_char = SOURCE->elements[SOURCE->size];
907907
next_token = lex_token();
908908
read_expr(parent, bb);
909909
}
910-
source_idx = t;
911-
next_char = SOURCE[source_idx];
910+
SOURCE->size = t;
911+
next_char = SOURCE->elements[SOURCE->size];
912912
next_token = lex_token();
913913
} else if (mac) {
914914
if (parent->macro)
@@ -918,18 +918,18 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
918918
mac->num_params = 0;
919919
lex_expect(T_identifier);
920920

921-
/* 'source_idx' has pointed at the first parameter */
921+
/* 'size' has pointed at the first parameter */
922922
while (!lex_peek(T_close_bracket, NULL)) {
923-
mac->params[mac->num_params++] = source_idx;
923+
mac->params[mac->num_params++] = SOURCE->size;
924924
do {
925925
next_token = lex_token();
926926
} while (next_token != T_comma &&
927927
next_token != T_close_bracket);
928928
}
929-
/* move 'source_idx' to the macro body */
930-
macro_return_idx = source_idx;
931-
source_idx = mac->start_source_idx;
932-
next_char = SOURCE[source_idx];
929+
/* move 'size' to the macro body */
930+
macro_return_idx = SOURCE->size;
931+
SOURCE->size = mac->start_source_idx;
932+
next_char = SOURCE->elements[SOURCE->size];
933933
lex_expect(T_close_bracket);
934934

935935
skip_newline = 0;
@@ -941,13 +941,13 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
941941
macro_return_idx = 0;
942942
} else if (macro_param_idx) {
943943
/* "expand" the argument from where it comes from */
944-
int t = source_idx;
945-
source_idx = macro_param_idx;
946-
next_char = SOURCE[source_idx];
944+
int t = SOURCE->size;
945+
SOURCE->size = macro_param_idx;
946+
next_char = SOURCE->elements[SOURCE->size];
947947
next_token = lex_token();
948948
read_expr(parent, bb);
949-
source_idx = t;
950-
next_char = SOURCE[source_idx];
949+
SOURCE->size = t;
950+
next_char = SOURCE->elements[SOURCE->size];
951951
next_token = lex_token();
952952
} else if (con) {
953953
ph1_ir = add_ph1_ir(OP_load_constant);
@@ -3072,17 +3072,17 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
30723072
mac->num_params = 0;
30733073
lex_expect(T_identifier);
30743074

3075-
/* 'source_idx' has pointed at the first parameter */
3075+
/* 'size' has pointed at the first parameter */
30763076
while (!lex_peek(T_close_bracket, NULL)) {
3077-
mac->params[mac->num_params++] = source_idx;
3077+
mac->params[mac->num_params++] = SOURCE->size;
30783078
do {
30793079
next_token = lex_token();
30803080
} while (next_token != T_comma && next_token != T_close_bracket);
30813081
}
3082-
/* move 'source_idx' to the macro body */
3083-
macro_return_idx = source_idx;
3084-
source_idx = mac->start_source_idx;
3085-
next_char = SOURCE[source_idx];
3082+
/* move 'size' to the macro body */
3083+
macro_return_idx = SOURCE->size;
3084+
SOURCE->size = mac->start_source_idx;
3085+
next_char = SOURCE->elements[SOURCE->size];
30863086
lex_expect(T_close_bracket);
30873087

30883088
skip_newline = 0;
@@ -3374,8 +3374,8 @@ void parse_internal()
33743374
GLOBAL_FUNC.fn->bbs = calloc(1, sizeof(basic_block_t));
33753375

33763376
/* lexer initialization */
3377-
source_idx = 0;
3378-
next_char = SOURCE[0];
3377+
SOURCE->size = 0;
3378+
next_char = SOURCE->elements[0];
33793379
lex_expect(T_start);
33803380

33813381
do {
@@ -3414,8 +3414,8 @@ void load_source_file(char *file)
34143414
strcpy(path + c, buffer + 10);
34153415
load_source_file(path);
34163416
} else {
3417-
strcpy(SOURCE + source_idx, buffer);
3418-
source_idx += strlen(buffer);
3417+
strcpy(SOURCE->elements + SOURCE->size, buffer);
3418+
SOURCE->size += strlen(buffer);
34193419
}
34203420
}
34213421
fclose(f);

tools/inliner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
9595
*/
9696
write_str("void __c(char *src) {\n");
9797
write_str(" for (int i = 0; src[i]; i++)\n");
98-
write_str(" SOURCE[source_idx++] = src[i];\n");
98+
write_str(" source_push(SOURCE, src[i]);\n");
9999
write_str("}\n");
100100

101101
write_str("void libc_generate() {\n");

0 commit comments

Comments
 (0)