Commits

Armin Rigo committed e79d88d

Fix the test by copying the frame before running it.

Comments (0)

Files changed (3)

 DuObject *Du_Progn(DuObject *cons, DuObject *locals);
 
 DuObject *DuFrame_New();
+DuObject *DuFrame_Copy(DuObject *frame);
 DuObject *DuFrame_GetSymbol(DuObject *frame, DuObject *symbol);
 void DuFrame_SetSymbol(DuObject *frame, DuObject *symbol, DuObject *value);
 void DuFrame_SetSymbolStr(DuObject *frame, char *name, DuObject *value);
     return (DuObject *)ob;
 }
 
+DuObject *DuFrame_Copy(DuObject *frame)
+{
+    DuFrame_Ensure("DuFrame_Copy", frame);
+    int i;
+    DuFrameObject *src = (DuFrameObject *)frame;
+    DuFrameObject *dst = (DuFrameObject *)DuFrame_New();
+    dst->entry_count = src->entry_count;
+    dst->entries = malloc(sizeof(struct dictentry) * src->entry_count);
+    assert(dst->entries);
+    for (i=0; i<src->entry_count; i++) {
+        struct dictentry *e = &src->entries[i];
+        Du_INCREF(e->symbol);
+        if (e->value        != NULL) Du_INCREF(e->value       );
+        if (e->func_arglist != NULL) Du_INCREF(e->func_arglist);
+        if (e->func_progn   != NULL) Du_INCREF(e->func_progn  );
+        dst->entries[i] = *e;
+    }
+    return (DuObject *)dst;
+}
+
 void frame_free(DuFrameObject *ob)
 {
     int i;
     if (setjmp(env) == 0) {
         _Du_AME_StartTransaction(&env);
         _Du_InitializeObjects();
-        DuObject *res = Du_Progn(fnode->fn_code, fnode->fn_frame);
+        DuObject *framecopy = DuFrame_Copy(fnode->fn_frame);
+        DuObject *res = Du_Progn(fnode->fn_code, framecopy);
         Du_DECREF(res);
+        Du_DECREF(framecopy);
         Du_DECREF(fnode->fn_frame);
         Du_DECREF(fnode->fn_code);
         _Du_MakeImmortal();