summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-12-10 16:52:26 -0800
committerKeith Packard <keithp@keithp.com>2017-12-11 12:20:25 -0800
commitbdafb4dfad89d92efec37ed826d5f22e9167e717 (patch)
treea04d3ad054cb56bd90a5e6998131da1216419156
parentb72638e60b6636b479b79bbf0047cf7409f58820 (diff)
altos/scheme: Stash cons across value allocation in compare
Large ints, strings and floats can cause allocation, requiring that the 'cons' pointer be stashed and retrieved in case it moved. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--src/scheme/ao_scheme_builtin.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/scheme/ao_scheme_builtin.c b/src/scheme/ao_scheme_builtin.c
index 6f9e1390..7a590735 100644
--- a/src/scheme/ao_scheme_builtin.c
+++ b/src/scheme/ao_scheme_builtin.c
@@ -319,6 +319,7 @@ ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
if (cons == orig_cons) {
ret = car;
+ ao_scheme_cons_stash(0, cons);
if (cons->cdr == AO_SCHEME_NIL) {
switch (op) {
case builtin_minus:
@@ -339,6 +340,7 @@ ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
break;
}
}
+ cons = ao_scheme_cons_fetch(0);
} else if (ao_scheme_integer_typep(rt) && ao_scheme_integer_typep(ct)) {
int32_t r = ao_scheme_poly_integer(ret);
int32_t c = ao_scheme_poly_integer(car);
@@ -390,7 +392,9 @@ ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
default:
break;
}
+ ao_scheme_cons_stash(0, cons);
ret = ao_scheme_integer_poly(r);
+ cons = ao_scheme_cons_fetch(0);
} else if (ao_scheme_number_typep(rt) && ao_scheme_number_typep(ct)) {
float r, c;
inexact:
@@ -416,12 +420,18 @@ ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
default:
break;
}
+ ao_scheme_cons_stash(0, cons);
ret = ao_scheme_float_get(r);
+ cons = ao_scheme_cons_fetch(0);
}
-
- else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus)
+ else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus) {
+ ao_scheme_cons_stash(0, cons);
ret = ao_scheme_string_poly(ao_scheme_string_cat(ao_scheme_poly_string(ret),
- ao_scheme_poly_string(car)));
+ ao_scheme_poly_string(car)));
+ cons = ao_scheme_cons_fetch(0);
+ if (!ret)
+ return ret;
+ }
else
return ao_scheme_error(AO_SCHEME_INVALID, "invalid args");
}