diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-10-02 23:52:22 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-10-02 23:55:03 +0200 |
commit | d03f4f4b0f770cdb16abf630179070c46031518d (patch) | |
tree | f6c746bdf64006acf0366d125b2deea5a14c2d1e | |
parent | a57aa8262ead82aaf2e9eec3d11d473186e7a33a (diff) |
ast: store function declarations as opcode offsets
We cannot use direct pointers since the opcode array might be reallocated
resulting in potentially changed memory addresses.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | ast.c | 13 | ||||
-rw-r--r-- | ast.h | 1 | ||||
-rw-r--r-- | eval.c | 2 |
3 files changed, 10 insertions, 6 deletions
@@ -285,13 +285,11 @@ func_to_string(struct json_object *v, struct printbuf *pb, int level, int flags) struct ut_op *op = json_object_get_userdata(v); struct ut_op *base, *decl, *name, *args, *arg; - if (!op->tag.data) - return 0; - /* find start of operand array */ - for (decl = op->tag.data, base = decl; base && !base->is_first; base--) + for (base = op; base && !base->is_first; base--) ; + decl = base + (op->tag.off ? op->tag.off - 1 : 0); name = base + (decl->tree.operand[0] ? decl->tree.operand[0] - 1 : 0); args = base + (decl->tree.operand[1] ? decl->tree.operand[1] - 1 : 0); @@ -313,10 +311,15 @@ ut_new_func(struct ut_op *decl) { struct json_object *val = xjs_new_object(); struct ut_op *op = xalloc(sizeof(*op)); + struct ut_op *base; + + /* find start of operand array */ + for (base = decl; base && !base->is_first; base--) + ; op->val = val; op->type = T_FUNC; - op->tag.data = decl; + op->tag.off = (decl - base) + 1; json_object_set_serializer(val, func_to_string, op, obj_free); @@ -72,6 +72,7 @@ struct ut_op { struct json_object *proto; size_t type; void *data; + uint32_t off; } tag; struct { uint32_t next; @@ -1050,7 +1050,7 @@ ut_invoke(struct ut_state *state, uint32_t off, struct json_object *scope, return cfn ? cfn(state, off, argvals) : NULL; } - decl = tag->tag.data; + decl = ut_get_op(state, tag->tag.off); arg = ut_get_op(state, decl ? decl->tree.operand[1] : 0); s = scope ? scope : ut_addscope(state, ut_get_off(state, decl)); |