Mercurial > hg > index.cgi
changeset 339:6138e304ab9a
Revert 3b5a45c6ab92
The speedup fix in 3b5a45c6ab92 contains some sort of bug related to operand
manipulation during expression simplification or copying. This leads to
crashes that so have have eluded tracing. Revert back to known working
version of the code, even though slower, to avoid regressions.
author | William Astle <lost@l-w.ca> |
---|---|
date | Fri, 08 Aug 2014 12:14:22 -0600 |
parents | 5d401d1eb3e9 |
children | b0fb675d1ed4 |
files | lwlib/lw_expr.c lwlib/lw_expr.h |
diffstat | 2 files changed, 88 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/lwlib/lw_expr.c Tue Aug 05 22:04:23 2014 -0600 +++ b/lwlib/lw_expr.c Fri Aug 08 12:14:22 2014 -0600 @@ -105,43 +105,24 @@ r = lw_alloc(sizeof(struct lw_expr_priv)); r -> operands = NULL; - r -> operand_tail = NULL; r -> value2 = NULL; r -> type = lw_expr_type_int; r -> value = 0; return r; } -static lw_expr_t lw_expr_remove_operand(lw_expr_t E, struct lw_expr_opers *o) -{ - lw_expr_t r; - if (E -> operands == o) - E -> operands = o -> next; - else - o -> prev -> next = o -> next; - - if (E -> operand_tail == o) - E -> operand_tail = o -> prev; - else - o -> next -> prev = o -> prev; - - r = o -> p; - lw_free(o); - return r; -} - -void lw_expr_destroy(lw_expr_t E); -static void lw_expr_remove_operands(lw_expr_t E) -{ - while (E -> operands) - lw_expr_destroy(lw_expr_remove_operand(E, E -> operands)); -} - void lw_expr_destroy(lw_expr_t E) { + struct lw_expr_opers *o; if (!E) return; - lw_expr_remove_operands(E); + while (E -> operands) + { + o = E -> operands; + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + } if (E -> type == lw_expr_type_var) lw_free(E -> value2); lw_free(E); @@ -172,18 +153,18 @@ void lw_expr_add_operand(lw_expr_t E, lw_expr_t O) { - struct lw_expr_opers *o; + struct lw_expr_opers *o, *t; o = lw_alloc(sizeof(struct lw_expr_opers)); o -> p = lw_expr_copy(O); o -> next = NULL; - o -> prev = E -> operand_tail; + for (t = E -> operands; t && t -> next; t = t -> next) + /* do nothing */ ; - if (E -> operands) - E -> operand_tail -> next = o; + if (t) + t -> next = o; else E -> operands = o; - E -> operand_tail = o; } lw_expr_t lw_expr_build_aux(int exprtype, va_list args) @@ -441,27 +422,18 @@ lw_expr_simplify_sortconstfirst(o -> p); } - for (o = E -> operands; o; ) + for (o = E -> operands; o; o = o -> next) { - struct lw_expr_opers *o2; - o2 = o -> next; if (o -> p -> type == lw_expr_type_int && o != E -> operands) { - // because o cannot be the first operand, we don't have to - // handle the single element list here - o2 = o -> next; - if (E -> operand_tail == o) - E -> operand_tail = o -> prev; - o -> prev -> next = o -> next; - if (o -> next) - o -> next -> prev = o -> prev; - E -> operands -> prev = o; + struct lw_expr_opers *o2; + for (o2 = E -> operands; o2 -> next != o; o2 = o2 -> next) + /* do nothing */ ; + o2 -> next = o -> next; o -> next = E -> operands; - o -> prev = NULL; E -> operands = o; - E -> operands = o; + o = o2; } - o = o2; } } @@ -613,8 +585,7 @@ lw_free(E -> value2); *E = *te; E -> operands = NULL; - E -> operand_tail = NULL; - + if (te -> type == lw_expr_type_var) E -> value2 = lw_strdup(te -> value2); for (o = te -> operands; o; o = o -> next) @@ -645,7 +616,6 @@ lw_free(E -> value2); *E = *te; E -> operands = NULL; - E -> operand_tail = NULL; if (te -> type == lw_expr_type_var) E -> value2 = lw_strdup(te -> value2); @@ -671,32 +641,20 @@ { if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_plus) { - if (o -> p -> operands) - { - if (E -> operands == NULL) - { - E -> operands = o -> p -> operands; - E -> operand_tail = o -> p -> operand_tail; - } - else - { - E -> operand_tail -> next = o -> p -> operands; - o -> p -> operands -> prev = E -> operand_tail; - E -> operand_tail = o -> p -> operand_tail; - } - o -> p -> operands = NULL; - o -> p -> operand_tail = NULL; - } + struct lw_expr_opers *o2; + // we have a + operation - bring operands up + + for (o2 = E -> operands; o2 && o2 -> next != o; o2 = o2 -> next) + /* do nothing */ ; + if (o2) + o2 -> next = o -> p -> operands; + else + E -> operands = o -> p -> operands; + for (o2 = o -> p -> operands; o2 -> next; o2 = o2 -> next) + /* do nothing */ ; + o2 -> next = o -> next; o -> p -> operands = NULL; lw_expr_destroy(o -> p); - if (o -> prev) - o -> prev -> next = o -> next; - else - E -> operands = o -> next; - if (o -> next) - o -> next -> prev = o -> prev; - else - E -> operand_tail = o -> prev; lw_free(o); goto tryagainplus; } @@ -711,32 +669,20 @@ { if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_times) { - if (o -> p -> operands) - { - if (E -> operands == NULL) - { - E -> operands = o -> p -> operands; - E -> operand_tail = o -> p -> operand_tail; - } - else - { - E -> operand_tail -> next = o -> p -> operands; - o -> p -> operands -> prev = E -> operand_tail; - E -> operand_tail = o -> p -> operand_tail; - } - o -> p -> operands = NULL; - o -> p -> operand_tail = NULL; - } + struct lw_expr_opers *o2; + // we have a + operation - bring operands up + + for (o2 = E -> operands; o2 && o2 -> next != o; o2 = o2 -> next) + /* do nothing */ ; + if (o2) + o2 -> next = o -> p -> operands; + else + E -> operands = o -> p -> operands; + for (o2 = o -> p -> operands; o2 -> next; o2 = o2 -> next) + /* do nothing */ ; + o2 -> next = o -> next; o -> p -> operands = NULL; lw_expr_destroy(o -> p); - if (o -> prev) - o -> prev -> next = o -> next; - else - E -> operands = o -> next; - if (o -> next) - o -> next -> prev = o -> prev; - else - E -> operand_tail = o -> prev; lw_free(o); goto tryagaintimes; } @@ -839,7 +785,13 @@ } - lw_expr_remove_operands(E); + while (E -> operands) + { + o = E -> operands; + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + } E -> type = lw_expr_type_int; E -> value = tr; return; @@ -852,9 +804,7 @@ e1 = lw_expr_create(); e1 -> operands = E -> operands; - e1 -> operand_tail = E -> operand_tail; E -> operands = 0; - E -> operand_tail = NULL; for (o = e1 -> operands; o; o = o -> next) { @@ -879,9 +829,7 @@ e1 = lw_expr_create(); e1 -> operands = E -> operands; - e1 -> operand_tail = E -> operand_tail; E -> operands = 0; - E -> operand_tail = NULL; for (o = e1 -> operands; o; o = o -> next) { @@ -906,7 +854,13 @@ if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) { // one operand of times is 0, replace operation with 0 - lw_expr_remove_operands(E); + while (E -> operands) + { + o = E -> operands; + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + } E -> type = lw_expr_type_int; E -> value = 0; return; @@ -1010,7 +964,9 @@ { r = lw_expr_copy(o -> p); } - lw_expr_destroy(lw_expr_remove_operand(E, E -> operands)); + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); } *E = *r; lw_free(r); @@ -1019,7 +975,13 @@ else if (c == 0) { // replace with 0 - lw_expr_remove_operands(E); + while (E -> operands) + { + o = E -> operands; + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + } E -> type = lw_expr_type_int; E -> value = 0; return; @@ -1029,12 +991,26 @@ // collapse out zero terms struct lw_expr_opers *o2; - for (o = E -> operands; o; o = o2) + for (o = E -> operands; o; o = o -> next) { - o2 = o -> next; if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) { - lw_expr_destroy(lw_expr_remove_operand(E, o)); + if (o == E -> operands) + { + E -> operands = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + o = E -> operands; + } + else + { + for (o2 = E -> operands; o2 -> next == o; o2 = o2 -> next) + /* do nothing */ ; + o2 -> next = o -> next; + lw_expr_destroy(o -> p); + lw_free(o); + o = o2; + } } } } @@ -1059,7 +1035,6 @@ lw_free(E -> operands -> next); lw_free(E -> operands); E -> operands = NULL; - E -> operand_tail = NULL; E -> value = lw_expr_oper_plus; for (o = E2 -> operands; o; o = o -> next) @@ -1068,6 +1043,9 @@ lw_expr_add_operand(E, t1); lw_expr_destroy(t1); } + + lw_expr_destroy(E2); + lw_expr_destroy(E3); } } else if (E -> operands -> next -> p -> type == lw_expr_type_int) @@ -1080,7 +1058,6 @@ lw_free(E -> operands -> next); lw_free(E -> operands); E -> operands = NULL; - E -> operand_tail = NULL; E -> value = lw_expr_oper_plus; for (o = E2 -> operands; o; o = o -> next)
--- a/lwlib/lw_expr.h Tue Aug 05 22:04:23 2014 -0600 +++ b/lwlib/lw_expr.h Fri Aug 08 12:14:22 2014 -0600 @@ -58,7 +58,6 @@ { lw_expr_t p; struct lw_expr_opers *next; - struct lw_expr_opers *prev; }; struct lw_expr_priv @@ -67,7 +66,6 @@ int value; // integer value void *value2; // misc pointer value struct lw_expr_opers *operands; // ptr to list of operands (for operators) - struct lw_expr_opers *operand_tail; // ptr to last operand }; typedef lw_expr_t lw_expr_fn_t(int t, void *ptr, void *priv);