Skip to content

Commit

Permalink
vala: avoid half-constructed vectors being garbage-collected.
Browse files Browse the repository at this point in the history
The clause in eval_ast() which evaluates each element of an input
vector into an output vector was holding the intermediate results in
an ordinary GLib.List, and putting them all into a vector at the end
of the evaluation. But that meant that nothing was preventing all
those values from being garbage-collected half way through.

Now we make an output Mal.Vector at the start of the process, and
point a GC.Root at it to ensure it stays around until we've finished
putting items in it.

This fixes the vala part of kanaka#418, I think.
  • Loading branch information
sgtatham committed Jul 16, 2019
1 parent 70305b6 commit 9cb52cf
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 45 deletions.
11 changes: 6 additions & 5 deletions vala/step2_eval.vala
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step3_env.vala
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step4_if_fn_do.vala
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ class Mal.Main: GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step5_tco.vala
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step6_file.vala
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step7_quote.vala
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step8_macros.vala
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/step9_try.vala
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down
11 changes: 6 additions & 5 deletions vala/stepA_mal.vala
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ class Mal.Main : GLib.Object {
return result;
}
if (ast is Mal.Vector) {
var results = new GLib.List<Mal.Val>();
for (var iter = (ast as Mal.Vector).iter();
iter.nonempty(); iter.step())
results.append(EVAL(iter.deref(), env));
return new Mal.Vector.from_list(results);
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
Expand Down

0 comments on commit 9cb52cf

Please sign in to comment.