Skip to content

Commit 9a8db0b

Browse files
Jim HsuChAoSUnItY
Jim Hsu
andcommitted
Replace SOURCE[] with dynamic array
Replaces the static string "SOURCE" in "src/global.c" with a dynamically allocated array using malloc and free. - Replaced SOURCE[] with a dynamically allocated array. - Updated related logic accordingly. Co-authored-by: Kyle Lin <[email protected]>
1 parent fcfe649 commit 9a8db0b

File tree

5 files changed

+117
-45
lines changed

5 files changed

+117
-45
lines changed

src/defs.h

+12
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,18 @@ typedef struct {
270270

271271
typedef struct basic_block basic_block_t;
272272

273+
/* Definition of a dynamic array structure for sources in src/globals.c
274+
* size: Current number of elements in the array
275+
* capacity: Number of elements that can be stored without resizing
276+
* elements: Pointer to the array of characters
277+
*/
278+
typedef struct {
279+
int size;
280+
int capacity;
281+
char *elements;
282+
} source_t;
283+
284+
273285
/* phase-2 IR definition */
274286
struct ph2_ir {
275287
opcode_t op;

src/globals.c

+67-9
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,62 @@ 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 *src)
857+
{
858+
if (src->size < src->capacity)
859+
return true;
860+
861+
src->capacity <<= 1;
862+
char *new_arr = malloc(src->capacity * sizeof(char));
863+
864+
if (!new_arr)
865+
return false;
866+
867+
memcpy(new_arr, src->elements, src->size * sizeof(char));
868+
869+
free(src->elements);
870+
src->elements = new_arr;
871+
872+
return true;
873+
}
874+
875+
bool source_push(source_t *src, char value)
876+
{
877+
if (!source_expand(src))
878+
return false;
879+
880+
src->elements[src->size] = value;
881+
src->size++;
882+
883+
return true;
884+
}
885+
886+
void source_release(source_t *src)
887+
{
888+
if (!src)
889+
return;
890+
891+
free(src->elements);
892+
free(src);
893+
}
894+
840895
/* This routine is required because the global variable initializations are
841896
* not supported now.
842897
*/
@@ -855,7 +910,7 @@ void global_init()
855910
BB_ARENA = arena_init(DEFAULT_ARENA_SIZE);
856911
PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *));
857912
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
858-
SOURCE = malloc(MAX_SOURCE);
913+
SOURCE = create_source(MAX_SOURCE);
859914
ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
860915
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));
861916

@@ -887,7 +942,7 @@ void global_release()
887942
arena_free(BB_ARENA);
888943
free(PH2_IR_FLATTEN);
889944
free(LABEL_LUT);
890-
free(SOURCE);
945+
source_release(SOURCE);
891946
free(ALIASES);
892947
free(CONSTANTS);
893948

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

910-
for (offset = source_idx; offset >= 0 && SOURCE[offset] != '\n'; offset--)
965+
for (offset = SOURCE->size; offset >= 0 && SOURCE->elements[offset] != '\n';
966+
offset--)
911967
;
912968

913969
start_idx = offset + 1;
914970

915-
for (offset = 0; offset < MAX_SOURCE && SOURCE[start_idx + offset] != '\n';
971+
for (offset = 0;
972+
offset < MAX_SOURCE && SOURCE->elements[start_idx + offset] != '\n';
916973
offset++) {
917-
diagnostic[i++] = SOURCE[start_idx + offset];
974+
diagnostic[i++] = SOURCE->elements[start_idx + offset];
918975
}
919976
diagnostic[i++] = '\n';
920977

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

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

src/lexer.c

+9-7
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

+28-28
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);
@@ -3075,17 +3075,17 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
30753075
mac->num_params = 0;
30763076
lex_expect(T_identifier);
30773077

3078-
/* 'source_idx' has pointed at the first parameter */
3078+
/* 'size' has pointed at the first parameter */
30793079
while (!lex_peek(T_close_bracket, NULL)) {
3080-
mac->params[mac->num_params++] = source_idx;
3080+
mac->params[mac->num_params++] = SOURCE->size;
30813081
do {
30823082
next_token = lex_token();
30833083
} while (next_token != T_comma && next_token != T_close_bracket);
30843084
}
3085-
/* move 'source_idx' to the macro body */
3086-
macro_return_idx = source_idx;
3087-
source_idx = mac->start_source_idx;
3088-
next_char = SOURCE[source_idx];
3085+
/* move 'size' to the macro body */
3086+
macro_return_idx = SOURCE->size;
3087+
SOURCE->size = mac->start_source_idx;
3088+
next_char = SOURCE->elements[SOURCE->size];
30893089
lex_expect(T_close_bracket);
30903090

30913091
skip_newline = 0;
@@ -3377,8 +3377,8 @@ void parse_internal()
33773377
GLOBAL_FUNC.fn->bbs = calloc(1, sizeof(basic_block_t));
33783378

33793379
/* lexer initialization */
3380-
source_idx = 0;
3381-
next_char = SOURCE[0];
3380+
SOURCE->size = 0;
3381+
next_char = SOURCE->elements[0];
33823382
lex_expect(T_start);
33833383

33843384
do {
@@ -3415,8 +3415,8 @@ void load_source_file(char *file)
34153415
snprintf(path + c + 1, inclusion_path_len, "%s", buffer + 10);
34163416
load_source_file(path);
34173417
} else {
3418-
strcpy(SOURCE + source_idx, buffer);
3419-
source_idx += strlen(buffer);
3418+
strcpy(SOURCE->elements + SOURCE->size, buffer);
3419+
SOURCE->size += strlen(buffer);
34203420
}
34213421
}
34223422
fclose(f);

tools/inliner.c

+1-1
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)