Merge pull request #4 from Hojun-Cho/compact

raise heap memory
This commit is contained in:
O_WRONLY 2024-09-02 07:39:55 +00:00 committed by GitHub
commit 4f27a4c9b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 279 additions and 149 deletions

View File

@ -42,7 +42,7 @@ bltinlookup(Object *obj)
{&Quote ,0}, {&Quote ,0},
{&Car ,0}, {&Car ,0},
{&Cdr ,0}, {&Cdr ,0},
0, {0},
}; };
for(int i = 0; bltins[i].sym; ++i){ for(int i = 0; bltins[i].sym; ++i){

4
dat.h
View File

@ -3,7 +3,6 @@
typedef uintptr_t u64; typedef uintptr_t u64;
typedef struct Object Object; typedef struct Object Object;
typedef Object* (*Bltinfn)(Object *env, Object *args); typedef Object* (*Bltinfn)(Object *env, Object *args);
typedef struct Object Object;
enum OType enum OType
{ {
@ -24,6 +23,7 @@ struct Object
enum OType type; /* type */ enum OType type; /* type */
int flag; /* flag */ int flag; /* flag */
Object *next; /* for gc */ Object *next; /* for gc */
Object *forward;
union{ union{
/* int */ /* int */
long num; long num;
@ -60,6 +60,7 @@ struct Object
*/ */
typedef struct typedef struct
{ {
int running;
void *memory; void *memory;
u64 cap; u64 cap;
u64 using; u64 using;
@ -79,6 +80,7 @@ typedef struct
}; };
}GC; }GC;
extern GC *gc;
extern Object Nil; extern Object Nil;
extern Object True; extern Object True;
extern Object False; extern Object False;

View File

@ -19,7 +19,7 @@ panic(char *fmt, ...)
void void
error(char *fmt, ...) error(char *fmt, ...)
{ {
extern jmp_buf err; extern jmp_buf *errptr;
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@ -27,6 +27,6 @@ error(char *fmt, ...)
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
va_end(ap); va_end(ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
longjmp(err, 1); longjmp(*errptr, 1);
exit(1); exit(1);
} }

33
eval.c
View File

@ -40,9 +40,9 @@ enter(Object *env, Object *vars, Object *args)
error("Cna't apply function argment dose not match"); error("Cna't apply function argment dose not match");
Object *id = vars->car; Object *id = vars->car;
Object *val = args->car; Object *val = args->car;
map = newacons(id, val, map); map = newacons(gc, id, val, map);
} }
return newenv(&Nil, map, env); return newenv(gc, &Nil, map, env);
} }
Object* Object*
@ -56,7 +56,7 @@ fnlambda(Object *env, Object *l)
} }
Object *params = l->car; Object *params = l->car;
Object *body = l->cdr; Object *body = l->cdr;
return newfn(env, params, body); return newfn(gc, env, params, body);
} }
Object* Object*
@ -79,7 +79,8 @@ fndefine(Object *env, Object *list)
Object *obj = find(env, list->car); Object *obj = find(env, list->car);
if(obj) if(obj)
return obj->cdr = val; return obj->cdr = val;
return env->vars = newacons(list->car, val, env->vars); env->vars = newacons(gc, list->car, val, env->vars);
return env->vars;
} }
Object* Object*
@ -91,7 +92,7 @@ fnplus(Object *env, Object *list)
error("+ take only number"); error("+ take only number");
sum += p->car->num; sum += p->car->num;
} }
return newint(sum); return newint(gc, sum);
} }
static Object* static Object*
@ -103,7 +104,7 @@ evallist(Object *env, Object *list)
error("type is not list"); error("type is not list");
Object *car = eval(env, list->car); Object *car = eval(env, list->car);
Object *cdr = evallist(env, list->cdr); Object *cdr = evallist(env, list->cdr);
return newcons(car, cdr); return newcons(gc, car, cdr);
} }
static Object* static Object*
@ -124,27 +125,29 @@ apply(Object *env, Object *fn, Object *args)
if(islist(args) == 0) if(islist(args) == 0)
error("args is not list type"); error("args is not list type");
switch(fn->type){ switch(fn->type){
case OBLTIN: default: error("can't apply");
Bltinfn blt = bltinlookup(fn); case OBLTIN:{
if(blt==0) Bltinfn blt = bltinlookup(fn);
error("not builtin type!"); if(blt==0)
return blt(env, args); error("not builtin type!");
return blt(env, args);
}
case OFUNC:{ case OFUNC:{
Object *elist = evallist(env, args); Object *elist = evallist(env, args);
Object*res = applyfn(fn, elist); Object*res = applyfn(fn, elist);
return res; return res;
} }
} }
error("can't apply");
return 0;
} }
Object* Object*
eval(Object *env, Object *obj) eval(Object *env, Object *obj)
{ {
switch(obj->type){ switch(obj->type){
case OINT: default:
error("can't eval");
case OSTRING: case OSTRING:
case OINT:
case OBLTIN: case OBLTIN:
case OSYMBOL: case OSYMBOL:
return obj; return obj;
@ -162,6 +165,4 @@ eval(Object *env, Object *obj)
return res; return res;
} }
} }
error("can't apply");
return 0;
} }

25
fn.h
View File

@ -7,21 +7,20 @@ Object* eval(Object *env, Object *expr);
/* new */ /* new */
Object* newint(long); Object* newint(GC *,long);
Object* newcons(Object*,Object*); Object* newcons(GC *,Object*,Object*);
Object* newenv(Object*name, Object *vars, Object *up); Object* newenv(GC *,Object*name, Object *vars, Object *up);
Object* newacons(Object*, Object*, Object*); Object* newacons(GC *,Object*, Object*, Object*);
Object* newsymbol(char*, int); Object* newsymbol(GC *,char*, int);
Object* newstr(int); Object* newstr(GC *,int);
Object* newfn(Object *env, Object *params, Object *body); Object* newfn(GC *,Object *env, Object *params, Object *body);
/* gc.c */ /* gc.c */
void gcstatus(void); Object* newobj(GC *,enum OType);
Object* newobj(enum OType); void* gcalloc(GC *,int);
void* gcalloc(int); void* gcralloc(GC *, void*, int);
void* gcralloc(void*, int); GC* newgc(void *top, int cap);
void gcinit(void *top, int cap); void gcrun(GC *);
void gcrun(void);
/* str.c */ /* str.c */
void strputc(Object*, int); void strputc(Object*, int);

282
gc.c
View File

@ -8,56 +8,160 @@
enum enum
{ {
USING = 1 << 1, USING = 1 << 1,
FORWARD = 1 << 2,
OFFSET = sizeof(int), OFFSET = sizeof(int),
}; };
GC gc = {0}; Object*
cloneobj(GC *dst, GC *src, Object *obj)
{
if(obj == 0)
return 0;
if(obj->type==OBLTIN||obj->type==OSYMBOL)
return obj;
if(obj->flag&FORWARD)
return obj->forward;
Object *p = newobj(dst, obj->type);
obj->flag |= FORWARD;
obj->forward = p;
switch(obj->type){
default: panic("unreachable");
case OINT:
p->num = obj->num;
break;
case OSTRING:
case OIDENT:{
int len = obj->ptr - obj->beg;
p->beg = gcalloc(dst, len + 1);
p->end = p->ptr = p->beg + len;
memcpy(p->beg, obj->beg, len + 1);
break;
}
case OCELL:
p->car = cloneobj(dst, src, obj->car);
p->cdr = cloneobj(dst, src, obj->cdr);
break;
case OENV:
p->name = cloneobj(dst, src, obj->name);
p->vars = cloneobj(dst, src, obj->vars);
p->up = cloneobj(dst, src, obj->up);
break;
case OFUNC:
p->params = cloneobj(dst, src, obj->params);
p->body = cloneobj(dst, src, obj->body);
p->env = cloneobj(dst, src, obj->env);
break;
}
return p;
}
Object*
moveobj(Object *p)
{
if(p == 0 || p->type == 0)
return 0;
switch(p->type){
default:
return p->forward;
case OBLTIN:
case OSYMBOL:
return p;
}
}
void void
gcfree(void *src) forwardstack(u64 bot, GC *dst, GC *src)
{
u64 pos, diff, *stk;
Object *moved, *org;
for(; bot < src->top; bot += sizeof(bot)){
stk = (u64*)(void**)bot;
if(src->ob <= *stk && *stk < src->oe){
diff = (*stk - src->ob) % sizeof(Object);
org = (Object*)(*stk - diff);
if((moved = moveobj(org)) == 0)
continue;
diff = (u64)org - *stk;
pos = (u64)moved + diff;
memcpy(stk, &pos, sizeof(pos));
}
else if(src->sb <= *stk && *stk < src->se)
for(org = src->objs; org; org = org->next){
if(org->type == OSTRING || org->type == OIDENT){
u64 beg = (u64)org->beg - OFFSET;
u64 end = beg + *(int*)beg;
if(beg <= *stk && *stk < end){
moved = moveobj(org);
diff = (*stk - beg);
pos = (u64)moved->beg - OFFSET + diff;
memcpy(stk, &pos, sizeof(pos));
break;
}
}
}
}
}
void
gccompact(int cap, GC *src)
{
void *_ = 0;
u64 bot = (u64)&_;
GC *dst = newgc((void*)src->top, cap);
dst->running = 1;
for(Object *p=src->objs; p; p=p->next)
cloneobj(dst, src, p);
forwardstack(bot, dst, src);
free(src->memory);
*src = *dst;
free(dst);
}
void
gcfree(GC *gc, void *src)
{ {
int *p = (int*)src - 1; int *p = (int*)src - 1;
int sz = *p; int sz = *p;
memset(p, 0, sz); memset(p, 0, sz);
gc.using -= sz; gc->using -= sz;
} }
void void
freeobj(Object *p) freeobj(GC *gc, Object *p)
{ {
gc.using -= sizeof(Object); gc->using -= sizeof(Object);
p->next = 0; p->next = 0;
switch(p->type){ switch(p->type){
default: default:
break; break;
case OSTRING: case OSTRING:
case OIDENT: case OIDENT:
gcfree(p->beg); gcfree(gc, p->beg);
break; break;
} }
memset(p, 0, sizeof(Object)); memset(p, 0, sizeof(Object));
if(gc.freed == 0) if(gc->freed == 0)
gc.freed = p; gc->freed = p;
else{ else{
p->next = gc.freed; p->next = gc->freed;
gc.freed = p; gc->freed = p;
} }
} }
void* void*
gcalloc(int sz) gcalloc(GC *gc, int sz)
{ {
sz += OFFSET; sz += OFFSET;
if(sz % OFFSET) sz = sz + OFFSET - (sz % OFFSET); if(sz % OFFSET) sz = sz + OFFSET - (sz % OFFSET);
for(u64 i = gc.sb; i < gc.se;){ for(u64 i = gc->sb; i < gc->se;){
u64 j = i; u64 j = i;
for(;j - i < sz; j += OFFSET){ for(;j - i < sz; j += OFFSET){
if(*(int*)(j) != 0) if(*(int*)(j) != 0)
break; break;
} }
if(j - i == sz){ if(j - i == sz){
gc.using += sz; gc->using += sz;
*(int*)i = sz; *(int*)i = sz;
i += OFFSET; i += OFFSET;
return (void*)i; return (void*)i;
@ -65,135 +169,149 @@ gcalloc(int sz)
i = j + *(int*)(j); i = j + *(int*)(j);
} }
panic("gccalloc : Not impl yet raise"); panic("gccalloc : Not impl yet raise");
return 0;
} }
void* void*
gcralloc(void *src, int sz) gcralloc(GC *gc, void *src, int sz)
{ {
void *dst = gcalloc(sz); void *dst = gcalloc(gc, sz);
int osz = ((int*)src)[-1]; int osz = ((int*)src)[-1];
memcpy(dst, src, osz); memcpy(dst, src, osz);
gcfree(src); gcfree(gc, src);
return dst; return dst;
} }
void void
mark(Object *obj) mark(GC *gc, Object *obj)
{ {
if(obj == 0 || obj->flag&USING) if(obj == 0 || obj->flag&USING ||
obj->type == 0|| obj->type==OBLTIN ||obj->type==OSYMBOL)
return; return;
obj->flag = USING; obj->flag = USING;
switch(obj->type){ switch(obj->type){
default:break;
case OCELL: case OCELL:
mark(obj->car); mark(gc, obj->car);
mark(obj->cdr); mark(gc, obj->cdr);
break; break;
case OENV: case OENV:
mark(obj->name); mark(gc, obj->name);
mark(obj->vars); mark(gc, obj->vars);
mark(obj->up); mark(gc, obj->up);
break; break;
case OFUNC: case OFUNC:
mark(obj->params); mark(gc, obj->params);
mark(obj->body); mark(gc, obj->body);
mark(obj->env); mark(gc, obj->env);
break; break;
} }
} }
void void
gcsweep(void) gcsweep(GC *gc)
{ {
Object *last = 0; Object *last = 0;
for(Object *p = gc.objs; p;){ for(Object *p = gc->objs; p;){
if(p->type == 0|| p->type==OBLTIN ||p->type==OSYMBOL)
return;
if(p->flag&USING){ if(p->flag&USING){
p->flag = 0; p->flag &= ~(USING);
last = p; last = p;
p = p->next; p = p->next;
}else{ }else{
Object *tmp = p; Object *tmp = p;
if(last == 0){ if(last == 0){
gc.objs = p->next; gc->objs = p->next;
}else{ }else{
last->next = p->next; last->next = p->next;
} }
p = p->next; p = p->next;
freeobj(tmp); freeobj(gc, tmp);
} }
} }
} }
int
isobj(u64 p)
{
if(gc.ob <= p && p < gc.oe){
p -= gc.ob;
return (p % sizeof(Object)) == 0;
}
return 0;
}
void void
gcmark(void) gcmark(GC *gc)
{ {
void *_ = 0; u64 _ = 0, stk, diff;
u64 bot = (u64)&_; u64 bot = (u64)&_;
for(; bot < gc.top; bot += sizeof(bot)){ Object *obj;
u64 val = (u64)*(void**)bot; for(; bot < gc->top; bot += sizeof(bot)){
if(isobj(val)) stk = (u64)*(void**)bot;
mark((Object*)val); if(gc->ob <= stk && stk <= gc->oe){
diff = (stk - gc->ob) % sizeof(Object);
obj = (Object*)(stk - diff);
mark(gc, obj);
}
else if(gc->sb <= stk && stk <= gc->se)
for(Object *obj = gc->objs; obj; obj = obj->next)
if(obj->type == OSTRING || obj->type == OIDENT){
u64 beg = (u64)obj->beg - OFFSET;
u64 end = beg + *(int*)beg;
if(beg <= stk && stk < end){
mark(gc, obj);
break;
}
}
} }
} }
void void
gcrun(void) gcrun(GC *src)
{ {
printf("before=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using); if(src->running)
return;
printf("BEFORE=> cap:%10ld using:%10ld remain:%10ld\n", src->cap, src->using, src->cap - src->using);
src->running = 1;
jmp_buf reg; jmp_buf reg;
setjmp(reg); if(setjmp(reg)==1){
gcmark(); printf("AFTER => cap:%10ld using:%10ld remain:%10ld\n", src->cap, src->using, src->cap - src->using);
gcsweep(); src->running = 0;
printf("after=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using); return;
}
gcmark(src);
gcsweep(src);
gccompact(src->cap + 500, src);
longjmp(reg, 1);
} }
Object* Object*
newobj(enum OType type) newobj(GC *gc, enum OType type)
{ {
if(gc.op + sizeof(Object) >= gc.oe){ gcrun(gc);
panic("Not impl yet newobj raise"); gc->using += sizeof(Object);
}
gcrun();
gc.using += sizeof(Object);
Object *r = 0; Object *r = 0;
if(gc.freed){ if(gc->freed){
r = gc.freed; r = gc->freed;
gc.freed = gc.freed->next; gc->freed = gc->freed->next;
}else{ }else{
r = (Object*)gc.op; r = (Object*)gc->op;
gc.op += sizeof(Object); gc->op += sizeof(Object);
} }
r->type = type; r->type = type;
if(gc.objs == 0) if(gc->objs)
gc.objs = r; r->next = gc->objs;
else{ return gc->objs = r;
r->next = gc.objs;
gc.objs = r;
}
return r;
} }
void GC*
gcinit(void *top, int cap) newgc(void *top, int cap)
{ {
gc.top = (u64)top; GC *gc = calloc(1, sizeof(GC));
if((gc.memory = malloc(cap)) == 0) if(gc == 0)
panic("can't alloc %d byte\n", sizeof(GC));
gc->top = (u64)top;
if((gc->memory = calloc(1, cap)) == 0)
panic("can't alloc %d byte\n", cap); panic("can't alloc %d byte\n", cap);
gc.cap = cap; gc->cap = cap;
gc.using = 0; gc->using = 0;
gc.op = gc.ob = (u64)gc.memory; gc->op = gc->ob = (u64)gc->memory;
gc.oe = gc.op + (float)cap * 0.64; gc->oe = gc->op + (float)cap * 0.64;
gc.sb = (u64)gc.memory + (float)cap * 0.64; gc->sb = (u64)gc->memory + (float)cap * 0.64;
gc.se = (u64)gc.memory + cap; gc->se = (u64)gc->memory + cap;
return gc;
} }

21
main.c
View File

@ -3,7 +3,8 @@
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
jmp_buf err; jmp_buf *errptr;
GC *gc;
static void static void
SExprint(Object *obj) SExprint(Object *obj)
@ -11,6 +12,8 @@ SExprint(Object *obj)
if(obj == 0) if(obj == 0)
return; return;
switch(obj->type){ switch(obj->type){
default:
return;
case OCELL: case OCELL:
printf("("); printf("(");
SExprint(obj->car); SExprint(obj->car);
@ -33,6 +36,7 @@ SExprint(Object *obj)
break; break;
case OENV: case OENV:
printf("<env>"); printf("<env>");
SExprint(obj->vars);
break; break;
case OLAMBDA: case OLAMBDA:
printf("<lambda>"); printf("<lambda>");
@ -58,21 +62,26 @@ printexpr(Object *obj)
static void static void
loop(void) loop(void)
{ {
Object *root = newenv(&Nil, &Nil, &Nil); Object *env = newenv(gc, &Nil, &Nil, &Nil);
if(setjmp(err) == 1){ jmp_buf buf;
errptr = &buf;
if(setjmp(buf) == 1){
skipline(); skipline();
gcrun();
} }
while(1){ while(1){
Object *res = nextexpr(); Object *res = nextexpr();
res = eval(root, res); res = eval(env, res);
printf("=============res===========\n");
printexpr(res); printexpr(res);
printf("=============env===========\n");
printexpr(env);
printf("===========================\n");
} }
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
gcinit(&argc, 4000); gc = newgc(&argc, 4000);
loop(); loop();
} }

View File

@ -10,7 +10,7 @@ OFILES=\
parser.o parser.o
AS=$(CC) -c AS=$(CC) -c
CFLAGS=-c -g -O0 CFLAGS=-c -g -O2 -Wall -std=c99
all: $(NAME) all: $(NAME)

34
obj.c
View File

@ -4,26 +4,26 @@
#include <string.h> #include <string.h>
Object* Object*
newint(long val) newint(GC *gc, long val)
{ {
Object *obj = newobj(OINT); Object *obj = newobj(gc, OINT);
obj->num = val; obj->num = val;
return obj; return obj;
} }
Object* Object*
newcons(Object *car, Object *cdr) newcons(GC *gc, Object *car, Object *cdr)
{ {
Object *obj = newobj(OCELL); Object *obj = newobj(gc, OCELL);
obj->car = car; obj->car = car;
obj->cdr = cdr; obj->cdr = cdr;
return obj; return obj;
} }
Object* Object*
newenv(Object* name, Object *vars, Object *up) newenv(GC *gc, Object* name, Object *vars, Object *up)
{ {
Object *obj = newobj(OENV); Object *obj = newobj(gc, OENV);
obj->name = name; obj->name = name;
obj->up = up; obj->up = up;
obj->vars = vars; obj->vars = vars;
@ -31,16 +31,16 @@ newenv(Object* name, Object *vars, Object *up)
} }
Object* Object*
newacons(Object *x, Object *y, Object *z) newacons(GC *gc, Object *x, Object *y, Object *z)
{ {
Object *cons = newcons(x, y); Object *cons = newcons(gc, x, y);
return newcons(cons, z); return newcons(gc, cons ,z);
} }
Object* Object*
newfn(Object *env, Object *params, Object *body) newfn(GC *gc, Object *env, Object *params, Object *body)
{ {
Object *fn = newobj(OFUNC); Object *fn = newobj(gc, OFUNC);
fn->params = params; fn->params = params;
fn->body = body; fn->body = body;
fn->env = env; fn->env = env;
@ -48,7 +48,7 @@ newfn(Object *env, Object *params, Object *body)
} }
Object* Object*
newsymbol(char *str, int len) newsymbol(GC *gc, char *str, int len)
{ {
static Object *syms[] = { static Object *syms[] = {
&Nil, &True, &False, &Minus, &Plus, &Nil, &True, &False, &Minus, &Plus,
@ -59,18 +59,18 @@ newsymbol(char *str, int len)
if(strlen(c->sym)==len && memcmp(c->sym, str, len) == 0) if(strlen(c->sym)==len && memcmp(c->sym, str, len) == 0)
return c; return c;
} }
Object *obj = newobj(OIDENT); Object *obj = newobj(gc, OIDENT);
obj->beg = gcalloc(len + 1); obj->beg = gcalloc(gc, len + 1);
obj->end = obj->ptr = obj->beg + len; obj->end = obj->ptr = obj->beg + len;
memcpy(obj->beg, str, len+1); memcpy(obj->beg, str, len+1);
return obj; return obj;
} }
Object* Object*
newstr(int len) newstr(GC *gc, int len)
{ {
Object *obj = newobj(OSTRING); Object *obj = newobj(gc, OSTRING);
obj->ptr = obj->beg = gcalloc(len + 1); obj->ptr = obj->beg = gcalloc(gc, len + 1);
obj->end = obj->beg + len; obj->end = obj->beg + len;
return obj; return obj;
} }

View File

@ -62,7 +62,7 @@ symbol(char c)
buf[len++] = get(); buf[len++] = get();
} }
buf[len] = 0; buf[len] = 0;
return newsymbol(buf, len); return newsymbol(gc, buf, len);
} }
static long static long
@ -79,14 +79,14 @@ quote(void)
{ {
Object *car = &Quote; Object *car = &Quote;
Object *ccdr = list(); Object *ccdr = list();
Object *cdr = newcons(ccdr, &Nil); Object *cdr = newcons(gc, ccdr, &Nil);
return newcons(car, cdr); return newcons(gc, car, cdr);
} }
static Object* static Object*
string(void) string(void)
{ {
Object *str = newstr(16); Object *str = newstr(gc, 16);
while(lookup() != '\"'){ while(lookup() != '\"'){
strputc(str, get()); strputc(str, get());
} }
@ -98,11 +98,11 @@ static Object*
atom(char c) atom(char c)
{ {
if(isdigit(c)) if(isdigit(c))
return newint(number()); return newint(gc, number());
get(); get();
if(c == '-'){ if(c == '-'){
if(isdigit(lookup())) if(isdigit(lookup()))
return newint(-number()); return newint(gc, -number());
else else
return symbol('-'); return symbol('-');
} }
@ -113,6 +113,7 @@ atom(char c)
return symbol(c); return symbol(c);
} }
error("bad char in list '%c'", c); error("bad char in list '%c'", c);
return 0;
} }
static Object* static Object*
@ -126,20 +127,20 @@ lparlist(void)
get(); get();
car = quote(); car = quote();
cdr = lparlist(); cdr = lparlist();
return newcons(car, cdr); return newcons(gc, car, cdr);
case '.': case '.':
get(); get();
return list(); return list();
case '(': case '(':
car = list(); car = list();
cdr = lparlist(); cdr = lparlist();
return newcons(car, cdr); return newcons(gc, car, cdr);
case ')': case ')':
return &Nil; return &Nil;
} }
car = atom(c); car = atom(c);
cdr = lparlist(); cdr = lparlist();
return newcons(car ,cdr); return newcons(gc, car ,cdr);
} }
static Object* static Object*

2
str.c
View File

@ -6,7 +6,7 @@ void
strraise(Object *s, int ns) strraise(Object *s, int ns)
{ {
int pos = s->ptr - s->beg; int pos = s->ptr - s->beg;
char *ptr = gcralloc(s->beg, ns + 1); char *ptr = gcralloc(gc, s->beg, ns + 1);
s->beg = ptr; s->beg = ptr;
s->ptr = s->beg + pos; s->ptr = s->beg + pos;
s->end = s->beg + ns; s->end = s->beg + ns;