comparison lwlib/lw_expr.c @ 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 3b5a45c6ab92
children 12e2453f8417
comparison
equal deleted inserted replaced
338:5d401d1eb3e9 339:6138e304ab9a
103 { 103 {
104 lw_expr_t r; 104 lw_expr_t r;
105 105
106 r = lw_alloc(sizeof(struct lw_expr_priv)); 106 r = lw_alloc(sizeof(struct lw_expr_priv));
107 r -> operands = NULL; 107 r -> operands = NULL;
108 r -> operand_tail = NULL;
109 r -> value2 = NULL; 108 r -> value2 = NULL;
110 r -> type = lw_expr_type_int; 109 r -> type = lw_expr_type_int;
111 r -> value = 0; 110 r -> value = 0;
112 return r; 111 return r;
113 } 112 }
114 113
115 static lw_expr_t lw_expr_remove_operand(lw_expr_t E, struct lw_expr_opers *o)
116 {
117 lw_expr_t r;
118 if (E -> operands == o)
119 E -> operands = o -> next;
120 else
121 o -> prev -> next = o -> next;
122
123 if (E -> operand_tail == o)
124 E -> operand_tail = o -> prev;
125 else
126 o -> next -> prev = o -> prev;
127
128 r = o -> p;
129 lw_free(o);
130 return r;
131 }
132
133 void lw_expr_destroy(lw_expr_t E);
134 static void lw_expr_remove_operands(lw_expr_t E)
135 {
136 while (E -> operands)
137 lw_expr_destroy(lw_expr_remove_operand(E, E -> operands));
138 }
139
140 void lw_expr_destroy(lw_expr_t E) 114 void lw_expr_destroy(lw_expr_t E)
141 { 115 {
116 struct lw_expr_opers *o;
142 if (!E) 117 if (!E)
143 return; 118 return;
144 lw_expr_remove_operands(E); 119 while (E -> operands)
120 {
121 o = E -> operands;
122 E -> operands = o -> next;
123 lw_expr_destroy(o -> p);
124 lw_free(o);
125 }
145 if (E -> type == lw_expr_type_var) 126 if (E -> type == lw_expr_type_var)
146 lw_free(E -> value2); 127 lw_free(E -> value2);
147 lw_free(E); 128 lw_free(E);
148 } 129 }
149 130
170 return r; 151 return r;
171 } 152 }
172 153
173 void lw_expr_add_operand(lw_expr_t E, lw_expr_t O) 154 void lw_expr_add_operand(lw_expr_t E, lw_expr_t O)
174 { 155 {
175 struct lw_expr_opers *o; 156 struct lw_expr_opers *o, *t;
176 157
177 o = lw_alloc(sizeof(struct lw_expr_opers)); 158 o = lw_alloc(sizeof(struct lw_expr_opers));
178 o -> p = lw_expr_copy(O); 159 o -> p = lw_expr_copy(O);
179 o -> next = NULL; 160 o -> next = NULL;
180 o -> prev = E -> operand_tail; 161 for (t = E -> operands; t && t -> next; t = t -> next)
181 162 /* do nothing */ ;
182 if (E -> operands) 163
183 E -> operand_tail -> next = o; 164 if (t)
165 t -> next = o;
184 else 166 else
185 E -> operands = o; 167 E -> operands = o;
186 E -> operand_tail = o;
187 } 168 }
188 169
189 lw_expr_t lw_expr_build_aux(int exprtype, va_list args) 170 lw_expr_t lw_expr_build_aux(int exprtype, va_list args)
190 { 171 {
191 lw_expr_t r; 172 lw_expr_t r;
439 { 420 {
440 if (o -> p -> type == lw_expr_type_oper && (o -> p -> value == lw_expr_oper_times || o -> p -> value == lw_expr_oper_plus)) 421 if (o -> p -> type == lw_expr_type_oper && (o -> p -> value == lw_expr_oper_times || o -> p -> value == lw_expr_oper_plus))
441 lw_expr_simplify_sortconstfirst(o -> p); 422 lw_expr_simplify_sortconstfirst(o -> p);
442 } 423 }
443 424
444 for (o = E -> operands; o; ) 425 for (o = E -> operands; o; o = o -> next)
445 { 426 {
446 struct lw_expr_opers *o2;
447 o2 = o -> next;
448 if (o -> p -> type == lw_expr_type_int && o != E -> operands) 427 if (o -> p -> type == lw_expr_type_int && o != E -> operands)
449 { 428 {
450 // because o cannot be the first operand, we don't have to 429 struct lw_expr_opers *o2;
451 // handle the single element list here 430 for (o2 = E -> operands; o2 -> next != o; o2 = o2 -> next)
452 o2 = o -> next; 431 /* do nothing */ ;
453 if (E -> operand_tail == o) 432 o2 -> next = o -> next;
454 E -> operand_tail = o -> prev;
455 o -> prev -> next = o -> next;
456 if (o -> next)
457 o -> next -> prev = o -> prev;
458 E -> operands -> prev = o;
459 o -> next = E -> operands; 433 o -> next = E -> operands;
460 o -> prev = NULL;
461 E -> operands = o; 434 E -> operands = o;
462 E -> operands = o; 435 o = o2;
463 } 436 }
464 o = o2;
465 } 437 }
466 } 438 }
467 439
468 void lw_expr_sortoperandlist(struct lw_expr_opers **o) 440 void lw_expr_sortoperandlist(struct lw_expr_opers **o)
469 { 441 {
611 lw_expr_destroy(o -> p); 583 lw_expr_destroy(o -> p);
612 if (E -> type == lw_expr_type_var) 584 if (E -> type == lw_expr_type_var)
613 lw_free(E -> value2); 585 lw_free(E -> value2);
614 *E = *te; 586 *E = *te;
615 E -> operands = NULL; 587 E -> operands = NULL;
616 E -> operand_tail = NULL; 588
617
618 if (te -> type == lw_expr_type_var) 589 if (te -> type == lw_expr_type_var)
619 E -> value2 = lw_strdup(te -> value2); 590 E -> value2 = lw_strdup(te -> value2);
620 for (o = te -> operands; o; o = o -> next) 591 for (o = te -> operands; o; o = o -> next)
621 { 592 {
622 lw_expr_t xxx; 593 lw_expr_t xxx;
643 lw_expr_destroy(o -> p); 614 lw_expr_destroy(o -> p);
644 if (E -> type == lw_expr_type_var) 615 if (E -> type == lw_expr_type_var)
645 lw_free(E -> value2); 616 lw_free(E -> value2);
646 *E = *te; 617 *E = *te;
647 E -> operands = NULL; 618 E -> operands = NULL;
648 E -> operand_tail = NULL;
649 619
650 if (te -> type == lw_expr_type_var) 620 if (te -> type == lw_expr_type_var)
651 E -> value2 = lw_strdup(te -> value2); 621 E -> value2 = lw_strdup(te -> value2);
652 for (o = te -> operands; o; o = o -> next) 622 for (o = te -> operands; o; o = o -> next)
653 { 623 {
669 tryagainplus: 639 tryagainplus:
670 for (o = E -> operands; o; o = o -> next) 640 for (o = E -> operands; o; o = o -> next)
671 { 641 {
672 if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_plus) 642 if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_plus)
673 { 643 {
674 if (o -> p -> operands) 644 struct lw_expr_opers *o2;
675 { 645 // we have a + operation - bring operands up
676 if (E -> operands == NULL) 646
677 { 647 for (o2 = E -> operands; o2 && o2 -> next != o; o2 = o2 -> next)
678 E -> operands = o -> p -> operands; 648 /* do nothing */ ;
679 E -> operand_tail = o -> p -> operand_tail; 649 if (o2)
680 } 650 o2 -> next = o -> p -> operands;
681 else 651 else
682 { 652 E -> operands = o -> p -> operands;
683 E -> operand_tail -> next = o -> p -> operands; 653 for (o2 = o -> p -> operands; o2 -> next; o2 = o2 -> next)
684 o -> p -> operands -> prev = E -> operand_tail; 654 /* do nothing */ ;
685 E -> operand_tail = o -> p -> operand_tail; 655 o2 -> next = o -> next;
686 }
687 o -> p -> operands = NULL;
688 o -> p -> operand_tail = NULL;
689 }
690 o -> p -> operands = NULL; 656 o -> p -> operands = NULL;
691 lw_expr_destroy(o -> p); 657 lw_expr_destroy(o -> p);
692 if (o -> prev)
693 o -> prev -> next = o -> next;
694 else
695 E -> operands = o -> next;
696 if (o -> next)
697 o -> next -> prev = o -> prev;
698 else
699 E -> operand_tail = o -> prev;
700 lw_free(o); 658 lw_free(o);
701 goto tryagainplus; 659 goto tryagainplus;
702 } 660 }
703 } 661 }
704 } 662 }
709 tryagaintimes: 667 tryagaintimes:
710 for (o = E -> operands; o; o = o -> next) 668 for (o = E -> operands; o; o = o -> next)
711 { 669 {
712 if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_times) 670 if (o -> p -> type == lw_expr_type_oper && o -> p -> value == lw_expr_oper_times)
713 { 671 {
714 if (o -> p -> operands) 672 struct lw_expr_opers *o2;
715 { 673 // we have a + operation - bring operands up
716 if (E -> operands == NULL) 674
717 { 675 for (o2 = E -> operands; o2 && o2 -> next != o; o2 = o2 -> next)
718 E -> operands = o -> p -> operands; 676 /* do nothing */ ;
719 E -> operand_tail = o -> p -> operand_tail; 677 if (o2)
720 } 678 o2 -> next = o -> p -> operands;
721 else 679 else
722 { 680 E -> operands = o -> p -> operands;
723 E -> operand_tail -> next = o -> p -> operands; 681 for (o2 = o -> p -> operands; o2 -> next; o2 = o2 -> next)
724 o -> p -> operands -> prev = E -> operand_tail; 682 /* do nothing */ ;
725 E -> operand_tail = o -> p -> operand_tail; 683 o2 -> next = o -> next;
726 }
727 o -> p -> operands = NULL;
728 o -> p -> operand_tail = NULL;
729 }
730 o -> p -> operands = NULL; 684 o -> p -> operands = NULL;
731 lw_expr_destroy(o -> p); 685 lw_expr_destroy(o -> p);
732 if (o -> prev)
733 o -> prev -> next = o -> next;
734 else
735 E -> operands = o -> next;
736 if (o -> next)
737 o -> next -> prev = o -> prev;
738 else
739 E -> operand_tail = o -> prev;
740 lw_free(o); 686 lw_free(o);
741 goto tryagaintimes; 687 goto tryagaintimes;
742 } 688 }
743 } 689 }
744 } 690 }
837 tr = E -> operands -> p -> value || E -> operands -> next -> p -> value; 783 tr = E -> operands -> p -> value || E -> operands -> next -> p -> value;
838 break; 784 break;
839 785
840 } 786 }
841 787
842 lw_expr_remove_operands(E); 788 while (E -> operands)
789 {
790 o = E -> operands;
791 E -> operands = o -> next;
792 lw_expr_destroy(o -> p);
793 lw_free(o);
794 }
843 E -> type = lw_expr_type_int; 795 E -> type = lw_expr_type_int;
844 E -> value = tr; 796 E -> value = tr;
845 return; 797 return;
846 } 798 }
847 799
850 lw_expr_t e1; 802 lw_expr_t e1;
851 int cval = 0; 803 int cval = 0;
852 804
853 e1 = lw_expr_create(); 805 e1 = lw_expr_create();
854 e1 -> operands = E -> operands; 806 e1 -> operands = E -> operands;
855 e1 -> operand_tail = E -> operand_tail;
856 E -> operands = 0; 807 E -> operands = 0;
857 E -> operand_tail = NULL;
858 808
859 for (o = e1 -> operands; o; o = o -> next) 809 for (o = e1 -> operands; o; o = o -> next)
860 { 810 {
861 if (o -> p -> type == lw_expr_type_int) 811 if (o -> p -> type == lw_expr_type_int)
862 cval += o -> p -> value; 812 cval += o -> p -> value;
877 lw_expr_t e1; 827 lw_expr_t e1;
878 int cval = 1; 828 int cval = 1;
879 829
880 e1 = lw_expr_create(); 830 e1 = lw_expr_create();
881 e1 -> operands = E -> operands; 831 e1 -> operands = E -> operands;
882 e1 -> operand_tail = E -> operand_tail;
883 E -> operands = 0; 832 E -> operands = 0;
884 E -> operand_tail = NULL;
885 833
886 for (o = e1 -> operands; o; o = o -> next) 834 for (o = e1 -> operands; o; o = o -> next)
887 { 835 {
888 if (o -> p -> type == lw_expr_type_int) 836 if (o -> p -> type == lw_expr_type_int)
889 cval *= o -> p -> value; 837 cval *= o -> p -> value;
904 for (o = E -> operands; o; o = o -> next) 852 for (o = E -> operands; o; o = o -> next)
905 { 853 {
906 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) 854 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0)
907 { 855 {
908 // one operand of times is 0, replace operation with 0 856 // one operand of times is 0, replace operation with 0
909 lw_expr_remove_operands(E); 857 while (E -> operands)
858 {
859 o = E -> operands;
860 E -> operands = o -> next;
861 lw_expr_destroy(o -> p);
862 lw_free(o);
863 }
910 E -> type = lw_expr_type_int; 864 E -> type = lw_expr_type_int;
911 E -> value = 0; 865 E -> value = 0;
912 return; 866 return;
913 } 867 }
914 } 868 }
1008 o = E -> operands; 962 o = E -> operands;
1009 if (o -> p -> type != lw_expr_type_int || o -> p -> value != 0) 963 if (o -> p -> type != lw_expr_type_int || o -> p -> value != 0)
1010 { 964 {
1011 r = lw_expr_copy(o -> p); 965 r = lw_expr_copy(o -> p);
1012 } 966 }
1013 lw_expr_destroy(lw_expr_remove_operand(E, E -> operands)); 967 E -> operands = o -> next;
968 lw_expr_destroy(o -> p);
969 lw_free(o);
1014 } 970 }
1015 *E = *r; 971 *E = *r;
1016 lw_free(r); 972 lw_free(r);
1017 return; 973 return;
1018 } 974 }
1019 else if (c == 0) 975 else if (c == 0)
1020 { 976 {
1021 // replace with 0 977 // replace with 0
1022 lw_expr_remove_operands(E); 978 while (E -> operands)
979 {
980 o = E -> operands;
981 E -> operands = o -> next;
982 lw_expr_destroy(o -> p);
983 lw_free(o);
984 }
1023 E -> type = lw_expr_type_int; 985 E -> type = lw_expr_type_int;
1024 E -> value = 0; 986 E -> value = 0;
1025 return; 987 return;
1026 } 988 }
1027 else if (c != t) 989 else if (c != t)
1028 { 990 {
1029 // collapse out zero terms 991 // collapse out zero terms
1030 struct lw_expr_opers *o2; 992 struct lw_expr_opers *o2;
1031 993
1032 for (o = E -> operands; o; o = o2) 994 for (o = E -> operands; o; o = o -> next)
1033 { 995 {
1034 o2 = o -> next;
1035 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0) 996 if (o -> p -> type == lw_expr_type_int && o -> p -> value == 0)
1036 { 997 {
1037 lw_expr_destroy(lw_expr_remove_operand(E, o)); 998 if (o == E -> operands)
999 {
1000 E -> operands = o -> next;
1001 lw_expr_destroy(o -> p);
1002 lw_free(o);
1003 o = E -> operands;
1004 }
1005 else
1006 {
1007 for (o2 = E -> operands; o2 -> next == o; o2 = o2 -> next)
1008 /* do nothing */ ;
1009 o2 -> next = o -> next;
1010 lw_expr_destroy(o -> p);
1011 lw_free(o);
1012 o = o2;
1013 }
1038 } 1014 }
1039 } 1015 }
1040 } 1016 }
1041 return; 1017 return;
1042 } 1018 }
1057 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) 1033 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus)
1058 { 1034 {
1059 lw_free(E -> operands -> next); 1035 lw_free(E -> operands -> next);
1060 lw_free(E -> operands); 1036 lw_free(E -> operands);
1061 E -> operands = NULL; 1037 E -> operands = NULL;
1062 E -> operand_tail = NULL;
1063 E -> value = lw_expr_oper_plus; 1038 E -> value = lw_expr_oper_plus;
1064 1039
1065 for (o = E2 -> operands; o; o = o -> next) 1040 for (o = E2 -> operands; o; o = o -> next)
1066 { 1041 {
1067 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); 1042 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p);
1068 lw_expr_add_operand(E, t1); 1043 lw_expr_add_operand(E, t1);
1069 lw_expr_destroy(t1); 1044 lw_expr_destroy(t1);
1070 } 1045 }
1046
1047 lw_expr_destroy(E2);
1048 lw_expr_destroy(E3);
1071 } 1049 }
1072 } 1050 }
1073 else if (E -> operands -> next -> p -> type == lw_expr_type_int) 1051 else if (E -> operands -> next -> p -> type == lw_expr_type_int)
1074 { 1052 {
1075 /* <other> TIMES <int> */ 1053 /* <other> TIMES <int> */
1078 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus) 1056 if (E2 -> type == lw_expr_type_oper && E2 -> value == lw_expr_oper_plus)
1079 { 1057 {
1080 lw_free(E -> operands -> next); 1058 lw_free(E -> operands -> next);
1081 lw_free(E -> operands); 1059 lw_free(E -> operands);
1082 E -> operands = NULL; 1060 E -> operands = NULL;
1083 E -> operand_tail = NULL;
1084 E -> value = lw_expr_oper_plus; 1061 E -> value = lw_expr_oper_plus;
1085 1062
1086 for (o = E2 -> operands; o; o = o -> next) 1063 for (o = E2 -> operands; o; o = o -> next)
1087 { 1064 {
1088 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p); 1065 t1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_times, E3, o -> p);