Skip to content

Commit b8b96db

Browse files
add metadata adding functions
1 parent 10b427f commit b8b96db

File tree

8 files changed

+208
-60
lines changed

8 files changed

+208
-60
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# need to set up AFL once parser is written https://medium.com/@ayushpriya10/fuzzing-applications-with-american-fuzzy-lop-afl-54facc65d102
2+
13
.PHONY: test64 builtest64 valgrind64 clean test32 buildtest32 valgrind32 deps show checkleaks
24

35
test: buildtest64 valgrind64 buildtest32 valgrind32 clean checkleaks

pickle.cpp

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,14 @@ bool needs_escape(char c) {
4242

4343
static void init_metadata(object* self, va_list args) {
4444
self->cells = new cell[4];
45-
self->cells[0].as_ptr = va_arg(args, object*);
46-
self->cells[1].as_obj = va_arg(args, object*);
47-
self->cells[2].as_obj = va_arg(args, object*);
48-
self->cells[3].as_obj = va_arg(args, object*);
45+
self->cells[0].as_obj = va_arg(args, object*); // line
46+
self->cells[1].as_obj = va_arg(args, object*); // column
47+
self->cells[2].as_obj = va_arg(args, object*); // file
48+
self->cells[3].as_obj = va_arg(args, object*); // prototypes list
4949
}
5050

51-
static void mark_metadata(object* self) {
52-
self->cells[0].as_obj->mark();
53-
self->cells[1].as_obj->mark();
54-
self->cells[2].as_obj->mark();
55-
self->cells[3].as_obj->mark();
51+
static void mark4(object* self) {
52+
for (int i = 0; i < 3; i++) self->cells[i].as_obj->mark();
5653
}
5754

5855
static void init_c_function(object* self, va_list args) {
@@ -106,19 +103,33 @@ static void init_error(object* self, va_list args) {
106103
self->cells[2].as_obj = va_arg(args, object*);
107104
}
108105

109-
static void mark_error(object* self) {
110-
for (int i = 0; i < 3; i++) self->cells[i].as_obj->mark();
106+
static void init_int(object* self, va_list args) {
107+
self->as_big_int = va_arg(args, int64_t);
108+
}
109+
110+
static int cmp_int(object* a, object* b) {
111+
return a->as_big_int - b->as_big_int;
112+
}
113+
114+
static void init_float(object* self, va_list args) {
115+
self->as_double = va_arg(args, double);
116+
}
117+
118+
static int cmp_float(object* a, object* b) {
119+
return (int)(a->as_double - b->as_double);
111120
}
112121

113-
const object_schema metadata_type("object_metadata", init_metadata, NULL, mark_metadata, tinobsy::schema_functions::finalize_cons);
114-
const object_schema cons_type("cons", tinobsy::schema_functions::init_cons, cmp_c_function, tinobsy::schema_functions::mark_cons, tinobsy::schema_functions::finalize_cons);
122+
const object_schema metadata_type("object_metadata", init_metadata, NULL, mark4, tinobsy::schema_functions::finalize_cons);
123+
const object_schema cons_type("cons", tinobsy::schema_functions::init_cons, NULL, tinobsy::schema_functions::mark_cons, tinobsy::schema_functions::finalize_cons);
115124
const object_schema partial_type("function_partial", init_function_partial, NULL, NULL, tinobsy::schema_functions::finalize_cons);
116-
const object_schema c_function_type("c_function", init_c_function, NULL, NULL, NULL);
117125
const object_schema string_type("string", init_string, cmp_string, mark_string, del_string);
118126
const object_schema symbol_type("symbol", tinobsy::schema_functions::init_str, tinobsy::schema_functions::cmp_str, NULL, tinobsy::schema_functions::finalize_str);
119-
const object_schema error_type("error", init_error, NULL, mark_error, tinobsy::schema_functions::finalize_cons);
127+
const object_schema c_function_type("c_function", init_c_function, cmp_c_function, NULL, NULL);
128+
const object_schema error_type("error", init_error, NULL, mark4, tinobsy::schema_functions::finalize_cons);
129+
const object_schema integer_type("int", init_int, cmp_int, NULL, NULL);
130+
const object_schema float_type("float", init_float, cmp_float, NULL, NULL);
120131

121-
object* pickle::cons_list(size_t len, ...) {
132+
object* pickle::list(size_t len, ...) {
122133
va_list args;
123134
va_start(args, len);
124135
object* head;
@@ -195,7 +206,7 @@ void pickle::run_next_thunk() {
195206
DBG("Data function");
196207
object* current_cont = this->make_partial(
197208
this->wrap_func(funcs::eval),
198-
this->cons_list(1, func), // args is ignored because they should already be added to env
209+
this->list(1, func), // args is ignored because they should already be added to env
199210
thunk->cells[2].as_obj,
200211
thunk->cells[3].as_obj,
201212
thunk->cells[4].as_obj);
@@ -219,9 +230,9 @@ void funcs::parse(pickle* runner, object* args, object* env, object* cont, objec
219230
else goto success;
220231
}
221232
TODO;
222-
// result = runner->make_error(runner->wrap_symbol("SyntaxError"), runner->cons_list(1, result), cont)
233+
// result = runner->wrap_error(runner->wrap_symbol("SyntaxError"), runner->list(1, result), cont)
223234
success:
224-
runner->set_retval(runner->cons_list(1, result), env, cont, fail_cont);
235+
runner->set_retval(runner->list(1, result), env, cont, fail_cont);
225236
s->cells[1].as_obj = result; // Save parse for later if constantly reparsing string (i.e. a loop)
226237
return;
227238
failure:
@@ -248,7 +259,7 @@ void funcs::eval(pickle* runner, object* args, object* env, object* cont, object
248259
env,
249260
runner->make_partial(
250261
runner->wrap_func(funcs::splice_match),
251-
runner->cons_list(2, runner->append(ast, NULL), NULL/*matched_pattern->match_info()*/),
262+
runner->list(2, runner->append(ast, NULL), NULL/*matched_pattern->match_info()*/),
252263
oldenv,
253264
runner->make_partial(
254265
runner->wrap_func(funcs::eval),
@@ -263,7 +274,7 @@ void funcs::eval(pickle* runner, object* args, object* env, object* cont, object
263274
));
264275
} else {
265276
// No matches so return unchanged
266-
runner->set_retval(runner->cons_list(1, ast), env, cont, fail_cont);
277+
runner->set_retval(runner->list(1, ast), env, cont, fail_cont);
267278
}
268279
}
269280

pickle.hpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ extern const object_schema string_type;
2929
extern const object_schema symbol_type;
3030
extern const object_schema stream_type;
3131
extern const object_schema error_type;
32+
extern const object_schema integer_type;
33+
extern const object_schema float_type;
3234

3335
class pickle : public tinobsy::vm {
3436
public:
3537
object* queue_head = NULL;
3638
object* queue_tail = NULL;
37-
object* cons_list(size_t len, ...);
39+
object* globals = NULL;
40+
object* list(size_t len, ...);
3841
object* append(object* l1, object* l2);
3942
void set_retval(object* args, object* env, object* cont, object* fail_cont);
4043
void set_failure(object* err, object* env, object* cont, object* fail_cont);
@@ -56,9 +59,32 @@ class pickle : public tinobsy::vm {
5659
inline object* cons(object* car, object* cdr) {
5760
return this->allocate(&cons_type, car, cdr);
5861
}
59-
inline object* make_error(object* type, object* details, object* continuation) {
62+
inline object* wrap_error(object* type, object* details, object* continuation) {
6063
return this->allocate(&error_type, type, details, continuation);
6164
}
65+
inline object* wrap_integer(int64_t x) {
66+
return this->allocate(&integer_type, x);
67+
}
68+
inline object* wrap_float(double x) {
69+
return this->allocate(&float_type, x);
70+
}
71+
inline object* wrap_metadata(object* line, object* col, object* file, object* prototypes) {
72+
return this->allocate(&metadata_type, line, col, file, prototypes);
73+
}
74+
inline object* wrap_metadata(int64_t line, int64_t col, const char* file, object* prototypes) {
75+
return this->allocate(&metadata_type, this->wrap_integer(line), this->wrap_integer(col), this->wrap_string(file), prototypes);
76+
}
77+
inline object* with_metadata(object* x, int64_t line, int64_t col, const char* file, object* prototypes) {
78+
if (x->meta) {
79+
x->meta->cells[0].as_obj = this->wrap_integer(line);
80+
x->meta->cells[1].as_obj = this->wrap_integer(col);
81+
x->meta->cells[2].as_obj = this->wrap_string(file);
82+
x->meta->cells[2].as_obj = prototypes;
83+
} else {
84+
x->meta = this->wrap_metadata(line, col, file, prototypes);
85+
}
86+
return x;
87+
}
6288
private:
6389
void mark_globals();
6490
};

pickle_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ void start_catch_segfault() {
2121
int main() {
2222
start_catch_segfault();
2323
auto vm = new pickle::pickle();
24-
auto foo = vm->wrap_string("thisWillCauseASyntaxError");
24+
auto foo = vm->with_metadata(vm->wrap_string("thisWillCauseASyntaxError"), 1, 1, "foo.pickle", vm->list(3, NULL, NULL, NULL));
2525
vm->run_next_thunk();
26+
vm->gc();
2627
printf("hello world\n");
2728
delete vm;
2829
return 0;

test/out32.txt

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,66 @@
11
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
2+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
3+
[tinobsy/tinobsy.cpp:110-init_cons]
4+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
5+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
6+
[tinobsy/tinobsy.cpp:110-init_cons]
7+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
8+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
9+
[tinobsy/tinobsy.cpp:110-init_cons]
10+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
211
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
3-
[pickle.cpp:84-init_string] init_string: thisWillCauseASyntaxError
12+
[pickle.cpp:81-init_string] init_string: thisWillCauseASyntaxError
413
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
514
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
6-
[pickle.cpp:178-run_next_thunk] run_next_thunk
7-
hello world
8-
[tinobsy/tinobsy.cpp:100-~vm] vm::~vm() {
15+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
16+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
17+
[pickle.cpp:81-init_string] init_string: foo.pickle
18+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
19+
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
20+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
21+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a int
22+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a int
23+
[tinobsy/tinobsy.cpp:47-allocate] New int not interned
24+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
25+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a int
26+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a int
27+
[tinobsy/tinobsy.cpp:41-allocate] Interned! int
28+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a int begin {
29+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
30+
[tinobsy/tinobsy.cpp:27-~object] }
31+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
32+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a object_metadata
33+
[pickle.cpp:189-run_next_thunk] run_next_thunk
34+
[tinobsy/tinobsy.cpp:79-gc] vm::gc() begin, 7 objects {
35+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
36+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
37+
[tinobsy/tinobsy.cpp:82-gc] garbage collect sweeping
38+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a object_metadata begin {
39+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
40+
[tinobsy/tinobsy.cpp:124-finalize_cons]
41+
[tinobsy/tinobsy.cpp:27-~object] }
42+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a int begin {
43+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
44+
[tinobsy/tinobsy.cpp:27-~object] }
945
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a string begin {
1046
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
1147
[tinobsy/tinobsy.cpp:27-~object] }
48+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a string begin {
49+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
50+
[tinobsy/tinobsy.cpp:27-~object] }
51+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
52+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
53+
[tinobsy/tinobsy.cpp:124-finalize_cons]
54+
[tinobsy/tinobsy.cpp:27-~object] }
55+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
56+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
57+
[tinobsy/tinobsy.cpp:124-finalize_cons]
58+
[tinobsy/tinobsy.cpp:27-~object] }
59+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
60+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
61+
[tinobsy/tinobsy.cpp:124-finalize_cons]
62+
[tinobsy/tinobsy.cpp:27-~object] }
63+
[tinobsy/tinobsy.cpp:95-gc] vm::gc() end, 0 objects, 7 freed }
64+
hello world
65+
[tinobsy/tinobsy.cpp:100-~vm] vm::~vm() {
1266
[tinobsy/tinobsy.cpp:106-~vm] }

test/out64.txt

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,66 @@
11
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
2+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
3+
[tinobsy/tinobsy.cpp:110-init_cons]
4+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
5+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
6+
[tinobsy/tinobsy.cpp:110-init_cons]
7+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
8+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a cons
9+
[tinobsy/tinobsy.cpp:110-init_cons]
10+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
211
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
3-
[pickle.cpp:84-init_string] init_string: thisWillCauseASyntaxError
12+
[pickle.cpp:81-init_string] init_string: thisWillCauseASyntaxError
413
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
514
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
6-
[pickle.cpp:178-run_next_thunk] run_next_thunk
7-
hello world
8-
[tinobsy/tinobsy.cpp:100-~vm] vm::~vm() {
15+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
16+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a string
17+
[pickle.cpp:81-init_string] init_string: foo.pickle
18+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a string
19+
[tinobsy/tinobsy.cpp:47-allocate] New string not interned
20+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
21+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a int
22+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a int
23+
[tinobsy/tinobsy.cpp:47-allocate] New int not interned
24+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
25+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a int
26+
[tinobsy/tinobsy.cpp:38-allocate] Trying to intern a int
27+
[tinobsy/tinobsy.cpp:41-allocate] Interned! int
28+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a int begin {
29+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
30+
[tinobsy/tinobsy.cpp:27-~object] }
31+
[tinobsy/tinobsy.cpp:33-allocate] Assertion succeeded: schema != NULL
32+
[tinobsy/tinobsy.cpp:34-allocate] vm::allocate() a object_metadata
33+
[pickle.cpp:189-run_next_thunk] run_next_thunk
34+
[tinobsy/tinobsy.cpp:79-gc] vm::gc() begin, 7 objects {
35+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
36+
[tinobsy/tinobsy.cpp:59-mark] NULL::mark()
37+
[tinobsy/tinobsy.cpp:82-gc] garbage collect sweeping
38+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a object_metadata begin {
39+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
40+
[tinobsy/tinobsy.cpp:124-finalize_cons]
41+
[tinobsy/tinobsy.cpp:27-~object] }
42+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a int begin {
43+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
44+
[tinobsy/tinobsy.cpp:27-~object] }
945
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a string begin {
1046
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
1147
[tinobsy/tinobsy.cpp:27-~object] }
48+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a string begin {
49+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
50+
[tinobsy/tinobsy.cpp:27-~object] }
51+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
52+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
53+
[tinobsy/tinobsy.cpp:124-finalize_cons]
54+
[tinobsy/tinobsy.cpp:27-~object] }
55+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
56+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
57+
[tinobsy/tinobsy.cpp:124-finalize_cons]
58+
[tinobsy/tinobsy.cpp:27-~object] }
59+
[tinobsy/tinobsy.cpp:22-~object] object::~object() for a cons begin {
60+
[tinobsy/tinobsy.cpp:25-~object] Assertion succeeded: xt != NULL
61+
[tinobsy/tinobsy.cpp:124-finalize_cons]
62+
[tinobsy/tinobsy.cpp:27-~object] }
63+
[tinobsy/tinobsy.cpp:95-gc] vm::gc() end, 0 objects, 7 freed }
64+
hello world
65+
[tinobsy/tinobsy.cpp:100-~vm] vm::~vm() {
1266
[tinobsy/tinobsy.cpp:106-~vm] }

test/valgrind32.txt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
==10620== Memcheck, a memory error detector
2-
==10620== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3-
==10620== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4-
==10620== Command: ./pickletest32
5-
==10620==
6-
==10620==
7-
==10620== HEAP SUMMARY:
8-
==10620== in use at exit: 0 bytes in 0 blocks
9-
==10620== total heap usage: 6 allocs, 6 frees, 23,118 bytes allocated
10-
==10620==
11-
==10620== All heap blocks were freed -- no leaks are possible
12-
==10620==
13-
==10620== For lists of detected and suppressed errors, rerun with: -s
14-
==10620== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
1+
==22550== Memcheck, a memory error detector
2+
==22550== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3+
==22550== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4+
==22550== Command: ./pickletest32
5+
==22550==
6+
==22550==
7+
==22550== HEAP SUMMARY:
8+
==22550== in use at exit: 0 bytes in 0 blocks
9+
==22550== total heap usage: 19 allocs, 19 frees, 23,349 bytes allocated
10+
==22550==
11+
==22550== All heap blocks were freed -- no leaks are possible
12+
==22550==
13+
==22550== For lists of detected and suppressed errors, rerun with: -s
14+
==22550== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

test/valgrind64.txt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
==10594== Memcheck, a memory error detector
2-
==10594== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3-
==10594== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4-
==10594== Command: ./pickletest64
5-
==10594==
6-
==10594==
7-
==10594== HEAP SUMMARY:
8-
==10594== in use at exit: 0 bytes in 0 blocks
9-
==10594== total heap usage: 6 allocs, 6 frees, 76,922 bytes allocated
10-
==10594==
11-
==10594== All heap blocks were freed -- no leaks are possible
12-
==10594==
13-
==10594== For lists of detected and suppressed errors, rerun with: -s
14-
==10594== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
1+
==22530== Memcheck, a memory error detector
2+
==22530== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
3+
==22530== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
4+
==22530== Command: ./pickletest64
5+
==22530==
6+
==22530==
7+
==22530== HEAP SUMMARY:
8+
==22530== in use at exit: 0 bytes in 0 blocks
9+
==22530== total heap usage: 19 allocs, 19 frees, 77,317 bytes allocated
10+
==22530==
11+
==22530== All heap blocks were freed -- no leaks are possible
12+
==22530==
13+
==22530== For lists of detected and suppressed errors, rerun with: -s
14+
==22530== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

0 commit comments

Comments
 (0)