diff options
author | glenda <glenda@cirno> | 2022-09-11 09:17:43 +0000 |
---|---|---|
committer | glenda <glenda@cirno> | 2022-09-11 09:17:43 +0000 |
commit | 759d2d541d943fe95138789477fa6faddf6e3e08 (patch) | |
tree | fc579523c78d4e073dc058777c9ab6a335087bde | |
parent | a1a9641baeab04b954420122b6fd1c9428a757b5 (diff) |
Clone all symbols in scope when spawning a new thread (closures), since the scope may get freed.
-rw-r--r-- | apl9.h | 1 | ||||
-rw-r--r-- | concurrency.c | 8 | ||||
-rw-r--r-- | runtime/start.apl | 2 | ||||
-rw-r--r-- | symbol.c | 28 |
4 files changed, 32 insertions, 7 deletions
@@ -301,6 +301,7 @@ vlong globalIO(void); void globalIOset(vlong); int globalDIV(void); void globalDIVset(int); +DfnFrame *dupscope(DfnFrame *); /* memory.c */ void *emalloc(ulong); diff --git a/concurrency.c b/concurrency.c index 80b9920..b49b43a 100644 --- a/concurrency.c +++ b/concurrency.c @@ -65,6 +65,7 @@ spawnthread(Function f, Array *name, Array *left, Array *right) Channel *setupdone = chancreate(sizeof(int), 0); SpawnData *sp = emalloc(sizeof(SpawnData)); sp->func = dupfunction(f); + sp->func.scope = dupscope(f.scope); sp->name = duparray(name); sp->left = left ? duparray(left) : nil; sp->right = duparray(right); @@ -192,12 +193,6 @@ newprocfn(void *data) ErrorGuard *eg = newerrorguard(mkscalarint(0), nil); /* make a catch-all error guard */ if(setjmp(eg->jmp)) displayerror(); - /* print("Thread %d: %S%S%S\n", - threadid(), - errorstr(td->lasterror), - (td->lasterror && td->lasterrormsg) ? L": " : L"", - td->lasterrormsg ? td->lasterrormsg : L""); - */ else{ int done = 1; send(sp->setupdone, &done); @@ -217,6 +212,7 @@ newprocfn(void *data) freearray(sp->name); freearray(sp->left); freearray(sp->right); + freedfnframe(sp->func.scope, 0); freefunction(sp->func); free(sp); free(td); diff --git a/runtime/start.apl b/runtime/start.apl index 70df0fb..d65d0bc 100644 --- a/runtime/start.apl +++ b/runtime/start.apl @@ -50,4 +50,4 @@ ⍵ } {∇ ⍵ handle {1 ⍵}⍇⍬} indented -}&'session'⊢0 ⎕self ('APL9> ') +}&'session'⊢0 ⎕self (6⍴' ') @@ -319,4 +319,32 @@ void setsyntaxerr(Datum *) { throwerror(nil, ESyntax); +} + +DfnFrame * +dupscope(DfnFrame *dfn) +{ + if(dfn == nil) + return nil; + + DfnFrame *new = emallocz(sizeof(DfnFrame), 1); + new->symtab = newsymtab(); + + /* copy ALL symbols which are in scope, into the new symtab */ + for(DfnFrame *d = dfn; d != nil; d = d->chain){ + /* Add all new symbols */ + for(int i = 0; i < d->symtab->nsyms; i++){ + Symbol *sym = d->symtab->syms[i]; + int found = 0; + for(int j = 0; j < new->symtab->nsyms && !found; j++) + if(runestrcmp(new->symtab->syms[i]->name, d->symtab->syms[j]->name) == 0) + found = 1; + if(!found){ + new->symtab->nsyms++; + new->symtab->syms = erealloc(new->symtab->syms, sizeof(Symbol *) * new->symtab->nsyms); + new->symtab->syms[new->symtab->nsyms-1] = dupsymbol(sym); + } + } + } + return new; }
\ No newline at end of file |