Skip to content

Commit 0d9a7d2

Browse files
author
Jim Hsu
committed
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.
1 parent 6196ab1 commit 0d9a7d2

File tree

5 files changed

+111
-40
lines changed

5 files changed

+111
-40
lines changed

src/defs.h

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

255255
typedef struct basic_block basic_block_t;
256256

257+
/* source dynamic array definition*/
258+
259+
typedef struct {
260+
int source_idx;
261+
int capacity;
262+
char *elements;
263+
} source_t;
264+
257265
/* phase-2 IR definition */
258266
struct ph2_ir {
259267
opcode_t op;

src/globals.c

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ int aliases_idx = 0;
5151
constant_t *CONSTANTS;
5252
int constants_idx = 0;
5353

54-
char *SOURCE;
55-
int source_idx = 0;
54+
source_t *SOURCE;
5655

5756
/* ELF sections */
5857

@@ -711,6 +710,64 @@ void add_insn(block_t *block,
711710
bb->insn_list.tail = n;
712711
}
713712

713+
source_t *create_source(int init_capacity)
714+
{
715+
source_t *array = malloc(sizeof(source_t));
716+
717+
if (!array) {
718+
return NULL;
719+
}
720+
721+
array->source_idx = 0;
722+
array->capacity = init_capacity;
723+
array->elements = malloc(array->capacity * sizeof(char));
724+
725+
return array;
726+
}
727+
728+
bool source_expand(source_t *self)
729+
{
730+
if (self->source_idx < self->capacity) {
731+
return true;
732+
}
733+
734+
self->capacity *= 2;
735+
char *new_arr = malloc(self->capacity * sizeof(char));
736+
737+
if (!new_arr) {
738+
return false;
739+
}
740+
741+
for (int i = 0; i < self->source_idx; i++) {
742+
new_arr[i] = self->elements[i];
743+
}
744+
745+
free(self->elements);
746+
self->elements = new_arr;
747+
748+
return true;
749+
}
750+
751+
bool source_push(source_t *self, char value)
752+
{
753+
if (!source_expand(self)) {
754+
return false;
755+
}
756+
757+
self->elements[self->source_idx] = value;
758+
self->source_idx++;
759+
760+
return true;
761+
}
762+
763+
void source_release(source_t *self)
764+
{
765+
if (self) {
766+
free(self->elements);
767+
free(self);
768+
}
769+
}
770+
714771
/* This routine is required because the global variable initializations are
715772
* not supported now.
716773
*/
@@ -727,7 +784,7 @@ void global_init()
727784
PH1_IR = malloc(MAX_IR_INSTR * sizeof(ph1_ir_t));
728785
PH2_IR = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t));
729786
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
730-
SOURCE = malloc(MAX_SOURCE);
787+
SOURCE = create_source(MAX_SOURCE);
731788
ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
732789
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));
733790

@@ -757,7 +814,7 @@ void global_release()
757814
free(PH1_IR);
758815
free(PH2_IR);
759816
free(LABEL_LUT);
760-
free(SOURCE);
817+
source_release(SOURCE);
761818
free(ALIASES);
762819
free(CONSTANTS);
763820

@@ -777,18 +834,20 @@ void error(char *msg)
777834
int offset, start_idx, i = 0;
778835
char diagnostic[512 /* MAX_LINE_LEN * 2 */];
779836

780-
for (offset = source_idx; offset >= 0 && SOURCE[offset] != '\n'; offset--)
837+
for (offset = SOURCE->source_idx;
838+
offset >= 0 && SOURCE->elements[offset] != '\n'; offset--)
781839
;
782840

783841
start_idx = offset + 1;
784842

785-
for (offset = 0; offset < MAX_SOURCE && SOURCE[start_idx + offset] != '\n';
843+
for (offset = 0;
844+
offset < MAX_SOURCE && SOURCE->elements[start_idx + offset] != '\n';
786845
offset++) {
787-
diagnostic[i++] = SOURCE[start_idx + offset];
846+
diagnostic[i++] = SOURCE->elements[start_idx + offset];
788847
}
789848
diagnostic[i++] = '\n';
790849

791-
for (offset = start_idx; offset < source_idx; offset++) {
850+
for (offset = start_idx; offset < SOURCE->source_idx; offset++) {
792851
diagnostic[i++] = ' ';
793852
}
794853

@@ -797,7 +856,8 @@ void error(char *msg)
797856
/* TODO: figure out the corresponding C source file path and report line
798857
* number.
799858
*/
800-
printf("Error %s at source location %d\n%s\n", msg, source_idx, diagnostic);
859+
printf("Error %s at source location %d\n%s\n", msg, SOURCE->source_idx,
860+
diagnostic);
801861
abort();
802862
}
803863

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->source_idx += 2;
162+
next_char = SOURCE->elements[SOURCE->source_idx];
163163
continue;
164164
}
165165
if (is_whitespace(next_char) ||
166166
(skip_newline && is_newline(next_char))) {
167-
next_char = SOURCE[++source_idx];
167+
SOURCE->source_idx++;
168+
next_char = SOURCE->elements[SOURCE->source_idx];
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->source_idx++;
178+
next_char = SOURCE->elements[SOURCE->source_idx];
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->source_idx + 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->source_idx = macro_return_idx;
607+
next_char = SOURCE->elements[SOURCE->source_idx];
606608
} else
607609
next_char = read_char(true);
608610
return lex_token_internal(aliasing);

src/parser.c

Lines changed: 24 additions & 23 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->source_idx;
412412
skip_macro_body();
413413
} else {
414414
/* Empty alias, may be dummy alias serves as include guard */
@@ -892,7 +892,7 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
892892

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

898898
if (!macro)
@@ -902,13 +902,14 @@ 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->source_idx =
906+
macro->params[macro->num_params - remainder + i];
907+
next_char = SOURCE->elements[SOURCE->source_idx];
907908
next_token = lex_token();
908909
read_expr(parent, bb);
909910
}
910-
source_idx = t;
911-
next_char = SOURCE[source_idx];
911+
SOURCE->source_idx = t;
912+
next_char = SOURCE->elements[SOURCE->source_idx];
912913
next_token = lex_token();
913914
} else if (mac) {
914915
if (parent->macro)
@@ -920,16 +921,16 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
920921

921922
/* 'source_idx' has pointed at the first parameter */
922923
while (!lex_peek(T_close_bracket, NULL)) {
923-
mac->params[mac->num_params++] = source_idx;
924+
mac->params[mac->num_params++] = SOURCE->source_idx;
924925
do {
925926
next_token = lex_token();
926927
} while (next_token != T_comma &&
927928
next_token != T_close_bracket);
928929
}
929930
/* 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];
931+
macro_return_idx = SOURCE->source_idx;
932+
SOURCE->source_idx = mac->start_source_idx;
933+
next_char = SOURCE->elements[SOURCE->source_idx];
933934
lex_expect(T_close_bracket);
934935

935936
skip_newline = 0;
@@ -941,13 +942,13 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
941942
macro_return_idx = 0;
942943
} else if (macro_param_idx) {
943944
/* "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];
945+
int t = SOURCE->source_idx;
946+
SOURCE->source_idx = macro_param_idx;
947+
next_char = SOURCE->elements[SOURCE->source_idx];
947948
next_token = lex_token();
948949
read_expr(parent, bb);
949-
source_idx = t;
950-
next_char = SOURCE[source_idx];
950+
SOURCE->source_idx = t;
951+
next_char = SOURCE->elements[SOURCE->source_idx];
951952
next_token = lex_token();
952953
} else if (con) {
953954
ph1_ir = add_ph1_ir(OP_load_constant);
@@ -3074,15 +3075,15 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
30743075

30753076
/* 'source_idx' has pointed at the first parameter */
30763077
while (!lex_peek(T_close_bracket, NULL)) {
3077-
mac->params[mac->num_params++] = source_idx;
3078+
mac->params[mac->num_params++] = SOURCE->source_idx;
30783079
do {
30793080
next_token = lex_token();
30803081
} while (next_token != T_comma && next_token != T_close_bracket);
30813082
}
30823083
/* 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];
3084+
macro_return_idx = SOURCE->source_idx;
3085+
SOURCE->source_idx = mac->start_source_idx;
3086+
next_char = SOURCE->elements[SOURCE->source_idx];
30863087
lex_expect(T_close_bracket);
30873088

30883089
skip_newline = 0;
@@ -3374,8 +3375,8 @@ void parse_internal()
33743375
GLOBAL_FUNC.fn->bbs = calloc(1, sizeof(basic_block_t));
33753376

33763377
/* lexer initialization */
3377-
source_idx = 0;
3378-
next_char = SOURCE[0];
3378+
SOURCE->source_idx = 0;
3379+
next_char = SOURCE->elements[0];
33793380
lex_expect(T_start);
33803381

33813382
do {
@@ -3414,8 +3415,8 @@ void load_source_file(char *file)
34143415
strcpy(path + c, buffer + 10);
34153416
load_source_file(path);
34163417
} else {
3417-
strcpy(SOURCE + source_idx, buffer);
3418-
source_idx += strlen(buffer);
3418+
strcpy(SOURCE->elements + SOURCE->source_idx, buffer);
3419+
SOURCE->source_idx += strlen(buffer);
34193420
}
34203421
}
34213422
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)