scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit c6ea791b9cac2e0e4486156b8751acd82da179dd
parent 7e46551105c8bc3b8b4b2b9bc02b36d494dce031
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 14 Nov 2014 13:35:02 -0500

Free expressions after using them

We were not freeing memory, so with big files this was a problem. This patch
adds a first solution to this problem, but something better must be done,
because in this moment one type is created by every function.

Diffstat:
Mcc1/cc1.h | 3+++
Mcc1/code.c | 15+++++++++++++++
Mcc1/stmt.c | 28++++++++++++++++++++++++----
3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -157,6 +157,7 @@ typedef struct node { void (*code)(struct node *); Type *type; uint8_t typeop; + uint8_t nchilds; struct { bool lvalue : 1; bool symbol: 1; @@ -209,6 +210,8 @@ extern Node *symcode(Symbol *sym), *fieldcode(Node *child, struct field *fp); +extern void freetree(Node *np); + #define NEGATE(n, v) ((n)->u.op ^= (v)) /* TODO: remove some of these ugly macros */ #define ISNODEBIN(n) ((n)->code == emitbin) diff --git a/cc1/code.c b/cc1/code.c @@ -1,6 +1,7 @@ #include <stdint.h> #include <stdio.h> +#include <stdlib.h> #include <cc.h> #include "cc1.h" @@ -58,12 +59,26 @@ node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds) np->code = code; np->type = tp; np->typeop = tp->op; + np->nchilds = nchilds; np->u = u; np->b.symbol = np->b.lvalue = 0; return np; } +void +freetree(Node *np) +{ + Node **p; + + if (!np) + return; + + for (p = np->childs; np->nchilds--; ++p) + freetree(*p); + free(np); +} + static void emitsym2(Symbol *sym) { diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -46,9 +46,15 @@ label(char *s, char define) static void stmtexp(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { - if (yytoken != ';') - emitexp(expr()); + Node *np = NULL;; + + if (yytoken != ';') { + np = expr(); + emitexp(np); + } + expect(';'); + freetree(np); } static Node * @@ -82,6 +88,7 @@ While(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) emitjump(begin, np); emiteloop(); emitlabel(end); + freetree(np); } static void @@ -113,12 +120,16 @@ For(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) emitjump(begin, econd); emiteloop(); emitlabel(end); + freetree(einit); + freetree(econd); + freetree(einc); } static void Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { Symbol *begin, *end; + Node *np; begin = install("", NS_LABEL); end = install("", NS_LABEL); @@ -127,9 +138,11 @@ Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) emitlabel(begin); stmt(end, begin, lswitch); expect(WHILE); - emitjump(begin, condition()); + np = condition(); + emitjump(begin, np); emiteloop(); emitlabel(end); + freetree(np); } static void @@ -153,6 +166,7 @@ Return(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) } emitret(tp); emitexp(np); + freetree(np); } static void @@ -229,11 +243,13 @@ Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) for (p = lcase.head; p; p = next) { emitcase(p->label, p->expr); next = p->next; + freetree(p->expr); free(p); } if (lcase.deflabel) emitdefault(lcase.deflabel); emitlabel(lbreak); + freetree(cond); } static void @@ -289,6 +305,7 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) } else { emitlabel(lelse); } + freetree(np); } void @@ -318,6 +335,7 @@ static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { void (*fun)(Symbol *lbreak, Symbol *lcont, Caselist *lswitch); + Node *np; switch (yytoken) { case '{': fun = context; break; @@ -338,7 +356,9 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) break; case '@': next(); - emitprint(expr()); + np = expr(); + emitprint(np); + freetree(np); return; } (*fun)(lbreak, lcont, lswitch);