aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-07-03 13:29:32 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-07-03 13:30:45 +0200
commitcb042b05828c4c89320bc9c7454c04c2761bbb9a (patch)
tree4147eab7da10a0b3987856d1e19788fe7c8f4119
parent90404ed2f62a872ffd9a555660b7ce17fae372d8 (diff)
downloadbusybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.tar.gz
busybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.tar.bz2
busybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.zip
awk: restore strdup elision optimization in assignment
function old new delta evaluate 3339 3387 +48 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/awk.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 649198d15..20672db9a 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -102,7 +102,7 @@ enum {
102#define VF_USER 0x0200 /* 1 = user input (may be numeric string) */ 102#define VF_USER 0x0200 /* 1 = user input (may be numeric string) */
103#define VF_SPECIAL 0x0400 /* 1 = requires extra handling when changed */ 103#define VF_SPECIAL 0x0400 /* 1 = requires extra handling when changed */
104#define VF_WALK 0x0800 /* 1 = variable has alloc'd x.walker list */ 104#define VF_WALK 0x0800 /* 1 = variable has alloc'd x.walker list */
105#define VF_FSTR 0x1000 /* 1 = var::string points to fstring buffer */ 105#define VF_FSTR 0x1000 /* 1 = don't free() var::string (not malloced, or is owned by something else) */
106#define VF_CHILD 0x2000 /* 1 = function arg; x.parent points to source */ 106#define VF_CHILD 0x2000 /* 1 = function arg; x.parent points to source */
107#define VF_DIRTY 0x4000 /* 1 = variable was set explicitly */ 107#define VF_DIRTY 0x4000 /* 1 = variable was set explicitly */
108 108
@@ -1371,6 +1371,12 @@ static node *parse_expr(uint32_t term_tc)
1371 cn->a.n = vn->a.n; 1371 cn->a.n = vn->a.n;
1372 if (tc & TS_BINOP) { 1372 if (tc & TS_BINOP) {
1373 cn->l.n = vn; 1373 cn->l.n = vn;
1374//FIXME: this is the place to detect and reject assignments to non-lvalues.
1375//Currently we allow "assignments" to consts and temporaries, nonsense like this:
1376// awk 'BEGIN { "qwe" = 1 }'
1377// awk 'BEGIN { 7 *= 7 }'
1378// awk 'BEGIN { length("qwe") = 1 }'
1379// awk 'BEGIN { (1+1) += 3 }'
1374 expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; 1380 expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP;
1375 if ((t_info & OPCLSMASK) == OC_PGETLINE) { 1381 if ((t_info & OPCLSMASK) == OC_PGETLINE) {
1376 /* it's a pipe */ 1382 /* it's a pipe */
@@ -3043,14 +3049,17 @@ static var *evaluate(node *op, var *res)
3043 case XC( OC_MOVE ): 3049 case XC( OC_MOVE ):
3044 debug_printf_eval("MOVE\n"); 3050 debug_printf_eval("MOVE\n");
3045 /* if source is a temporary string, jusk relink it to dest */ 3051 /* if source is a temporary string, jusk relink it to dest */
3046//Disabled: if R.v is numeric but happens to have cached R.v->string, 3052 if (R.v == TMPVAR1
3047//then L.v ends up being a string, which is wrong 3053 && !(R.v->type & VF_NUMBER)
3048// if (R.v == TMPVAR1 && R.v->string) { 3054 /* Why check !NUMBER? if R.v is a number but has cached R.v->string,
3049// res = setvar_p(L.v, R.v->string); 3055 * L.v ends up a string, which is wrong */
3050// R.v->string = NULL; 3056 /*&& R.v->string - always not NULL (right?) */
3051// } else { 3057 ) {
3058 res = setvar_p(L.v, R.v->string); /* avoids strdup */
3059 R.v->string = NULL;
3060 } else {
3052 res = copyvar(L.v, R.v); 3061 res = copyvar(L.v, R.v);
3053// } 3062 }
3054 break; 3063 break;
3055 3064
3056 case XC( OC_TERNARY ): 3065 case XC( OC_TERNARY ):