summaryrefslogtreecommitdiffhomepage
path: root/eval.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-09-02 22:20:50 +0200
committerJo-Philipp Wich <jo@mein.io>2020-09-02 22:20:50 +0200
commit2bce10151bace89d6ed38475da816f469b73418d (patch)
treece38f3b4719af2710aa1a32e77e6fb845d86b070 /eval.c
parentac76b7b8370775b66f1f7f78d68888afa6bc059a (diff)
eval: properly increase/decrease refcounts when dealing with scopes
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index 283c790..5a2beb4 100644
--- a/eval.c
+++ b/eval.c
@@ -305,7 +305,7 @@ ut_getref(struct ut_state *state, struct ut_opcode *op, struct json_object **key
*key = op->val;
- return scope;
+ return json_object_get(scope);
}
else {
*key = NULL;
@@ -336,6 +336,8 @@ ut_getref_required(struct ut_state *state, struct ut_opcode *op, struct json_obj
"Syntax error: Invalid left-hand side operand %s", tokennames[op->type]);
}
+ json_object_put(scope);
+
*key = NULL;
return rv;
}
@@ -429,11 +431,17 @@ ut_execute_assign(struct ut_state *state, struct ut_opcode *op)
{
struct ut_opcode *label = op->operand[0];
struct ut_opcode *value = op->operand[1];
- struct json_object *scope, *key;
+ struct json_object *scope, *key, *val;
scope = ut_getref_required(state, label, &key);
- return key ? ut_setval(scope, key, ut_execute_op(state, value)) : scope;
+ if (!key)
+ return scope;
+
+ val = ut_setval(scope, key, ut_execute_op(state, value));
+ ut_putval(scope);
+
+ return val;
}
static struct json_object *
@@ -769,6 +777,8 @@ ut_execute_inc_dec(struct ut_state *state, struct ut_opcode *op)
val = ut_getval(scope, key);
+ ut_putval(scope);
+
if (ut_cast_number(val, &n, &d) == json_type_double)
nval = json_object_new_double_rounded(d + (op->type == T_INC ? 1.0 : -1.0));
else
@@ -1159,7 +1169,7 @@ ut_execute_break_cont(struct ut_state *state, struct ut_opcode *op)
static struct json_object *
ut_execute_op(struct ut_state *state, struct ut_opcode *op)
{
- struct json_object *scope, *key;
+ struct json_object *scope, *key, *val;
switch (op->type) {
case T_NUMBER:
@@ -1193,13 +1203,22 @@ ut_execute_op(struct ut_state *state, struct ut_opcode *op)
scope = ut_getref(state, op, &key);
state->ctx = scope;
- return ut_getval(scope, key);
+ val = ut_getval(scope, key);
+ ut_putval(scope);
+
+ return val;
case T_DOT:
scope = ut_getref_required(state, op, &key);
state->ctx = scope;
- return key ? ut_getval(scope, key) : scope;
+ if (!key)
+ return scope;
+
+ val = ut_getval(scope, key);
+ ut_putval(scope);
+
+ return val;
case T_LBRACK:
/* postfix access */
@@ -1207,7 +1226,13 @@ ut_execute_op(struct ut_state *state, struct ut_opcode *op)
scope = ut_getref_required(state, op, &key);
state->ctx = scope;
- return key ? ut_getval(scope, key) : scope;
+ if (!key)
+ return scope;
+
+ val = ut_getval(scope, key);
+ json_object_put(scope);
+
+ return val;
}
return ut_execute_list(state, op->operand[0]);