summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h3
-rw-r--r--concurrency.c15
-rw-r--r--eval.c2
-rw-r--r--functions.c6
-rw-r--r--memory.c6
-rw-r--r--symbol.c37
6 files changed, 34 insertions, 35 deletions
diff --git a/apl9.h b/apl9.h
index 99f9f98..bfb4d99 100644
--- a/apl9.h
+++ b/apl9.h
@@ -188,7 +188,6 @@ struct Symtab
int nsyms;
int io; /* index origin */
int div; /* division method */
- uvlong refs;
Symtab *chain;
Symbol **syms;
};
@@ -328,7 +327,7 @@ void freeerrorguards(ErrorGuard *);
void freeerrorguard(ErrorGuard *);
/* functions.c */
-Array *runfunc(Function, Array *,Array *);
+Array *runfunc(Function, Array *, Array *);
Array *rundfn(Rune *, Datum *, Datum *, Array *, Array *);
Array *runtrain(Function *, int, Array *, Array *, Array *);
diff --git a/concurrency.c b/concurrency.c
index 08dfdbc..b45ee08 100644
--- a/concurrency.c
+++ b/concurrency.c
@@ -70,9 +70,7 @@ spawnthread(Function f, Array *name, Array *left, Array *right)
SpawnData *sp = emallocz(sizeof(SpawnData), 1);
sp->func = dupfunction(f);
- Symtab *scope = dupscope(f.scope);
- freesymtab(sp->func.scope);
- sp->func.scope = scope;
+ sp->func.scope = dupscope(f.scope);
sp->name = duparray(name);
sp->left = left ? duparray(left) : nil;
sp->right = duparray(right);
@@ -224,6 +222,7 @@ newprocfn(SpawnData *sp)
freearray(sp->name);
freearray(sp->left);
freearray(sp->right);
+ freesymtab(sp->func.scope);
freefunction(sp->func);
free(sp);
free(td);
@@ -271,6 +270,7 @@ threadproperty(vlong t, vlong p)
ThreadData *td = nil;
Array *res = nil;
int mailcount = 0;
+ int framecount = 0;
lock(&threadlock);
for(int i = 0; i < nthreads && td == nil; i++)
if(threads[i]->id == t)
@@ -292,9 +292,16 @@ threadproperty(vlong t, vlong p)
qunlock(&td->lock);
res = mkscalarint(mailcount);
break;
- case 3: /* used stacksize */
+ case 3: /* used C stacksize */
res = mkscalarint(td->stackused);
break;
+ case 4: /* DfnFrame count */
+ qlock(&td->lock);
+ for(DfnFrame *f = td->currentdfn; f != nil; f = f->prev)
+ framecount++;
+ qunlock(&td->lock);
+ res = mkscalarint(framecount);
+ break;
default:
unlock(&threadlock);
throwerror(L"Invalid thread property", EDomain);
diff --git a/eval.c b/eval.c
index 9df4f4a..cd9b95a 100644
--- a/eval.c
+++ b/eval.c
@@ -362,8 +362,6 @@ monadop(Datum *left, Datum *right)
incdatumref(left);
result->func.left = nil;
result->func.scope = right->operator.scope;
- if(result->func.scope)
- result->func.scope->refs++;
return result;
}
diff --git a/functions.c b/functions.c
index 0dd898d..102590d 100644
--- a/functions.c
+++ b/functions.c
@@ -135,6 +135,7 @@ runfunc(Function f, Array *left, Array *right)
Rune *code;
Datum *lefto = nil;
Datum *righto = nil;
+
if(f.type == FunctypeDfn)
code = f.dfn;
else{
@@ -143,9 +144,10 @@ runfunc(Function f, Array *left, Array *right)
code = f.operator.dop;
}
- pushdfnframe(code, f.scope, lefto, righto, left, right);
+ DfnFrame *fr = pushdfnframe(code, f.scope, lefto, righto, left, right);
Datum *dfnres = evalline(code, nil, 0);
- popdfnframe();
+ if(fr == getcurrentdfn())
+ popdfnframe();
result = dfnres->array; /* TODO what if the evaluation failed */
if(dfnres->tag != ArrayTag || result == nil)
diff --git a/memory.c b/memory.c
index 3416ea4..5dd879b 100644
--- a/memory.c
+++ b/memory.c
@@ -167,7 +167,6 @@ void
freefunction(Function f)
{
freearray(f.left);
- freesymtab(f.scope);
switch(f.type){
case FunctypeDfn:
free(f.dfn);
@@ -198,7 +197,6 @@ freeoperator(Operator o)
{
freedatum(o.left);
freedatum(o.right);
- freesymtab(o.scope);
switch(o.type){
case OperatortypeDop:
free(o.dop);
@@ -228,8 +226,6 @@ dupfunction(Function f)
Function g = f;
if(g.left)
incarrayref(g.left);
- if(g.scope)
- g.scope->refs++;
switch(f.type){
case FunctypeDfn:
@@ -263,8 +259,6 @@ Operator
dupoperator(Operator o)
{
Operator p = o;
- if(p.scope)
- p.scope->refs++;
if(p.left)
incdatumref(p.left);
diff --git a/symbol.c b/symbol.c
index 3cb8a9b..ad06203 100644
--- a/symbol.c
+++ b/symbol.c
@@ -23,17 +23,14 @@ getsym(Rune *name, int fresh)
Symtab *tab;
for(tab = getcurrentsymtab(); tab; tab = tab->chain){
for(int i = 0; i < tab->nsyms; i++){
- if(runestrcmp(tab->syms[i]->name, name) == 0){
- freesymtab(tab);
+ if(runestrcmp(tab->syms[i]->name, name) == 0)
return tab->syms[i];
- }
}
if(fresh)
break;
}
/* make sure to allocate in the most local scope if the symbol is not found */
- freesymtab(tab);
tab = getcurrentsymtab();
tab->nsyms++;
@@ -44,7 +41,6 @@ getsym(Rune *name, int fresh)
tab->syms[tab->nsyms-1]->setfn = nil;
tab->syms[tab->nsyms-1]->value = nil;
- freesymtab(tab);
return tab->syms[tab->nsyms-1];
}
@@ -56,10 +52,7 @@ newsymtab(Symtab *chain)
tab->syms = nil;
tab->io = globalIO();
tab->div = globalDIV();
- tab->refs = 1;
tab->chain = chain;
- if(chain)
- chain->refs++;
return tab;
}
@@ -80,7 +73,6 @@ dupsymtab(Symtab *tab)
{
Symtab *new = newsymtab(tab->chain);
memcpy(new, tab, sizeof(Symtab));
- new->refs = 1;
new->syms = emalloc(sizeof(Symbol*) * new->nsyms);
for(int i = 0; i < tab->nsyms; i++)
new->syms[i] = dupsymbol(tab->syms[i]);
@@ -92,10 +84,8 @@ freesymtab(Symtab *tab)
{
if(tab == nil)
return;
- if(tab->refs-- > 1)
- return;
- if(tab == globalsymtab)
+ if(tab == globalsymtab) /* Never free the global symtab */
return;
int i;
@@ -104,7 +94,6 @@ freesymtab(Symtab *tab)
freedatum(s->value);
free(s->name);
}
- freesymtab(tab->chain);
free(tab->syms);
free(tab);
}
@@ -162,6 +151,7 @@ pushdfnframe(Rune *code, Symtab *scope, Datum *lefto, Datum *righto, Array *left
incarrayref(right);
new->prev = td->currentdfn;
new->errorguards = nil;
+
td->currentdfn = new;
return new;
}
@@ -345,7 +335,19 @@ dupscope(Symtab *old)
if(!found){
new->nsyms++;
new->syms = erealloc(new->syms, sizeof(Symbol *) * new->nsyms);
- new->syms[new->nsyms-1] = dupsymbol(sym);
+ Symbol *s = dupsymbol(sym);
+ new->syms[new->nsyms-1] = s;
+ if(s->value){
+ switch(s->value->tag){
+ case FunctionTag:
+ s->value->func.scope = new;
+ break;
+ case MonadicOpTag:
+ case DyadicOpTag:
+ s->value->operator.scope = new;
+ break;
+ }
+ }
}
}
}
@@ -356,11 +358,8 @@ Symtab *
getcurrentsymtab(void)
{
DfnFrame *dfn = getcurrentdfn();
- if(dfn == nil){
- globalsymtab->refs++;
+ if(dfn == nil)
return globalsymtab;
- }else{
- dfn->symtab->refs++;
+ else
return dfn->symtab;
- }
} \ No newline at end of file