summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ast.c34
-rw-r--r--ast.h1
-rw-r--r--eval.c2
3 files changed, 36 insertions, 1 deletions
diff --git a/ast.c b/ast.c
index 5d42b56..bba1316 100644
--- a/ast.c
+++ b/ast.c
@@ -132,6 +132,40 @@ json_object_new_null_obj(void) {
return d;
}
+static void
+obj_free(struct json_object *v, void *ud)
+{
+ struct ut_tagvalue *tag = json_object_get_userdata(v);
+
+ json_object_put(tag->proto);
+ free(ud);
+}
+
+struct json_object *
+ut_new_object(struct ut_state *s, struct json_object *proto) {
+ struct json_object *val = json_object_new_object();
+ struct ut_tagvalue *tag;
+
+ if (!val)
+ return NULL;
+
+ tag = calloc(1, sizeof(*tag));
+
+ if (!tag) {
+ json_object_put(val);
+
+ return NULL;
+ }
+
+ tag->val = val;
+ tag->type = T_LBRACE;
+ tag->proto = json_object_get(proto);
+
+ json_object_set_serializer(val, NULL, tag, obj_free);
+
+ return tag->val;
+}
+
static int
func_to_string(struct json_object *v, struct printbuf *pb, int level, int flags)
{
diff --git a/ast.h b/ast.h
index 979b975..d1c8193 100644
--- a/ast.h
+++ b/ast.h
@@ -101,6 +101,7 @@ void ut_free(struct ut_state *s);
struct ut_opcode *ut_new_func(struct ut_state *s, struct ut_opcode *name, struct ut_opcode *args, struct ut_opcode *body);
+struct json_object *ut_new_object(struct ut_state *s, struct json_object *proto);
struct json_object *json_object_new_double_rounded(double v);
struct json_object *json_object_new_null_obj(void);
diff --git a/eval.c b/eval.c
index 68fda6e..88f3cee 100644
--- a/eval.c
+++ b/eval.c
@@ -777,7 +777,7 @@ ut_execute_list(struct ut_state *state, struct ut_opcode *op)
static struct json_object *
ut_execute_object(struct ut_state *state, struct ut_opcode *op)
{
- struct json_object *obj = json_object_new_object();
+ struct json_object *obj = ut_new_object(state, NULL);
struct ut_opcode *key, *val;
if (!obj)