diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-10-06 19:05:21 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-10-06 20:00:39 +0200 |
commit | c874751224237aaed7509960d14823d9c06e6eb5 (patch) | |
tree | 79e3786fb61bb9d918a1f87a8c2d750d920ebe3b | |
parent | 8fb8da605419c427605ca91c67b367c9a4cd0eec (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.c | 9 | ||||
-rw-r--r-- | tests/02_runtime/02_this | 22 |
2 files changed, 31 insertions, 0 deletions
@@ -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"); +%} |