aboutsummaryrefslogtreecommitdiffstats
path: root/interpret.h
diff options
context:
space:
mode:
Diffstat (limited to 'interpret.h')
-rw-r--r--interpret.h27
1 files changed, 13 insertions, 14 deletions
diff --git a/interpret.h b/interpret.h
index 3bb4532e..9d7b423e 100644
--- a/interpret.h
+++ b/interpret.h
@@ -23,13 +23,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+/*
+ * If "r" is a field, valref should normally be > 1, because the field is
+ * created initially with valref 1, and valref should be bumped when it is
+ * pushed onto the stack by Op_field_spec. On the other hand, if we are
+ * assigning to $n, then Op_store_field calls unref(*lhs) before assigning
+ * the new value, so that decrements valref. So if the RHS is a field with
+ * valref 1, that effectively means that this is an assignment like "$n = $n",
+ * so a no-op, other than triggering $0 reconstitution.
+ */
#define UNFIELD(l, r) \
{ \
/* if was a field, turn it into a var */ \
- if ((r->flags & FIELD) == 0) { \
- l = r; \
- } else if (r->valref == 1) { \
- r->flags &= ~FIELD; \
+ if ((r->flags & MALLOC) != 0 || r->valref == 1) { \
l = r; \
} else { \
l = dupnode(r); \
@@ -129,13 +135,10 @@ top:
case Op_push_i:
m = pc->memory;
if (! do_traditional && (m->flags & INTLSTR) != 0) {
- char *orig, *trans, save;
+ char *orig, *trans;
- save = m->stptr[m->stlen];
- m->stptr[m->stlen] = '\0';
orig = m->stptr;
trans = dgettext(TEXTDOMAIN, orig);
- m->stptr[m->stlen] = save;
m = make_string(trans, strlen(trans));
} else
UPREF(m);
@@ -357,12 +360,8 @@ uninitialized_scalar:
lhs = r_get_field(t1, (Func_ptr *) 0, true);
decr_sp();
DEREF(t1);
- /* only for $0, up ref count */
- if (*lhs == fields_arr[0]) {
- r = *lhs;
- UPREF(r);
- } else
- r = dupnode(*lhs);
+ r = *lhs;
+ UPREF(r);
PUSH(r);
break;