summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-10-06 19:05:21 +0200
committerJo-Philipp Wich <jo@mein.io>2020-10-06 20:00:39 +0200
commitc874751224237aaed7509960d14823d9c06e6eb5 (patch)
tree79e3786fb61bb9d918a1f87a8c2d750d920ebe3b
parent8fb8da605419c427605ca91c67b367c9a4cd0eec (diff)
eval: restore context pointer of first evaluated dot/bracket expression
When an expression such as `foo.bar(a.b, c.d)` is evaluated, the state context pointer will point to `c` while we need `foo` when invoking functions. Since the context pointer is only relevant for function calls and since for function call opcodes, the lhs expression is always the first operand, there is no need to store the context of subsequent ops. Adjust the ut_get_operands() procedure to restore state->ctx to the result of the first evaluated operand. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--eval.c9
-rw-r--r--tests/02_runtime/02_this22
2 files changed, 31 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 1803355..074baa5 100644
--- a/eval.c
+++ b/eval.c
@@ -746,6 +746,7 @@ ut_cmp(int how, struct json_object *v1, struct json_object *v2)
static struct json_object *
_ut_get_operands(struct ut_state *state, struct ut_op *op, size_t n, struct json_object **v)
{
+ struct json_object *ctx = NULL;
struct ut_op *child;
size_t i, j;
@@ -759,7 +760,12 @@ _ut_get_operands(struct ut_state *state, struct ut_op *op, size_t n, struct json
else
v[i] = NULL;
+ if (i == 0)
+ ctx = json_object_get(state->ctx);
+
if (ut_is_type(v[i], T_EXCEPTION)) {
+ json_object_put(ctx);
+
for (j = 0; j < i; j++)
json_object_put(v[j]);
@@ -767,6 +773,9 @@ _ut_get_operands(struct ut_state *state, struct ut_op *op, size_t n, struct json
}
}
+ json_object_put(state->ctx);
+ state->ctx = ctx;
+
return NULL;
}
diff --git a/tests/02_runtime/02_this b/tests/02_runtime/02_this
index d41be7f..e1efd80 100644
--- a/tests/02_runtime/02_this
+++ b/tests/02_runtime/02_this
@@ -23,3 +23,25 @@ true
print(o.test(), "\n");
%}
-- End --
+
+Test that the context is properly restored if function call arguments are
+dot or bracket expressions as well.
+
+-- Expect stdout --
+true
+true
+-- End --
+
+-- Testcase --
+{%
+ local o = {
+ test: function() {
+ return (this === o);
+ }
+ };
+
+ local dummy = { foo: true, bar: false };
+
+ print(o.test(dummy.foo, dummy.bar), "\n");
+ print(o.test(dummy.foo, o.test(dummy.foo, dummy.bar)), "\n");
+%}