Skip to content

Commit 21527d7

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 21527d7

File tree

5 files changed

+117
-45
lines changed

5 files changed

+117
-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: 71 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,66 @@ 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+
843+
if (!array) {
844+
return NULL;
845+
}
846+
847+
array->size = 0;
848+
array->capacity = init_capacity;
849+
array->elements = malloc(array->capacity * sizeof(char));
850+
if (!array->elements) {
851+
free(array);
852+
return NULL;
853+
}
854+
855+
return array;
856+
}
857+
858+
bool source_expand(source_t *self)
859+
{
860+
if (self->size < self->capacity) {
861+
return true;
862+
}
863+
864+
self->capacity <<= 1;
865+
char *new_arr = malloc(self->capacity * sizeof(char));
866+
867+
if (!new_arr) {
868+
return false;
869+
}
870+
871+
memcpy(new_arr, self->elements, self->size * sizeof(char));
872+
873+
free(self->elements);
874+
self->elements = new_arr;
875+
876+
return true;
877+
}
878+
879+
bool source_push(source_t *self, char value)
880+
{
881+
if (!source_expand(self)) {
882+
return false;
883+
}
884+
885+
self->elements[self->size] = value;
886+
self->size++;
887+
888+
return true;
889+
}
890+
891+
void source_release(source_t *self)
892+
{
893+
if (self) {
894+
free(self->elements);
895+
free(self);
896+
}
897+
}
898+
840899
/* This routine is required because the global variable initializations are
841900
* not supported now.
842901
*/
@@ -855,7 +914,7 @@ void global_init()
855914
BB_ARENA = arena_init(DEFAULT_ARENA_SIZE);
856915
PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *));
857916
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
858-
SOURCE = malloc(MAX_SOURCE);
917+
SOURCE = create_source(MAX_SOURCE);
859918
ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
860919
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));
861920

@@ -887,7 +946,7 @@ void global_release()
887946
arena_free(BB_ARENA);
888947
free(PH2_IR_FLATTEN);
889948
free(LABEL_LUT);
890-
free(SOURCE);
949+
source_release(SOURCE);
891950
free(ALIASES);
892951
free(CONSTANTS);
893952

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

910-
for (offset = source_idx; offset >= 0 && SOURCE[offset] != '\n'; offset--)
969+
for (offset = SOURCE->size; offset >= 0 && SOURCE->elements[offset] != '\n';
970+
offset--)
911971
;
912972

913973
start_idx = offset + 1;
914974

915-
for (offset = 0; offset < MAX_SOURCE && SOURCE[start_idx + offset] != '\n';
975+
for (offset = 0;
976+
offset < MAX_SOURCE && SOURCE->elements[start_idx + offset] != '\n';
916977
offset++) {
917-
diagnostic[i++] = SOURCE[start_idx + offset];
978+
diagnostic[i++] = SOURCE->elements[start_idx + offset];
918979
}
919980
diagnostic[i++] = '\n';
920981

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

@@ -927,7 +988,8 @@ void error(char *msg)
927988
/* TODO: figure out the corresponding C source file path and report line
928989
* number.
929990
*/
930-
printf("Error %s at source location %d\n%s\n", msg, source_idx, diagnostic);
991+
printf("Error %s at source location %d\n%s\n", msg, SOURCE->size,
992+
diagnostic);
931993
abort();
932994
}
933995

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)