sed 's/.*/#define JQ_VERSION "&"/' $^ > $@
main.c: version.gen.h
-JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c
+JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_alloc.c
jq_test: CFLAGS += -DJQ_DEBUG=1
jq_test: $(JQ_SRC) jq_test.c
#include "bytecode.h"
#include "opcode.h"
+#include "jv_alloc.h"
static int bytecode_operation_length(uint16_t* codeptr) {
int length = opcode_describe(*codeptr)->length;
}
void symbol_table_free(struct symbol_table* syms) {
- free(syms->cfunctions);
- free(syms);
+ jv_mem_free(syms->cfunctions);
+ jv_mem_free(syms);
}
void bytecode_free(struct bytecode* bc) {
- free(bc->code);
+ jv_mem_free(bc->code);
jv_free(bc->constants);
for (int i=0; i<bc->nsubfunctions; i++)
bytecode_free(bc->subfunctions[i]);
if (!bc->parent)
symbol_table_free(bc->globals);
- free(bc->subfunctions);
- free(bc);
+ jv_mem_free(bc->subfunctions);
+ jv_mem_free(bc);
}
+#define _GNU_SOURCE // for strdup
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "compile.h"
#include "bytecode.h"
#include "locfile.h"
+#include "jv_alloc.h"
/*
The intermediate representation for jq filters is as a sequence of
};
static inst* inst_new(opcode op) {
- inst* i = malloc(sizeof(inst));
+ inst* i = jv_mem_alloc(sizeof(inst));
i->next = i->prev = 0;
i->op = op;
i->bytecode_pos = -1;
}
static void inst_free(struct inst* i) {
- free(i->symbol);
+ jv_mem_free(i->symbol);
block_free(i->subfn);
block_free(i->arglist);
if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) {
jv_free(i->imm.constant);
}
- free(i);
+ jv_mem_free(i);
}
static block inst_block(inst* i) {
}
}
if (bc->nsubfunctions) {
- bc->subfunctions = malloc(sizeof(struct bytecode*) * bc->nsubfunctions);
+ bc->subfunctions = jv_mem_alloc(sizeof(struct bytecode*) * bc->nsubfunctions);
for (inst* curr = b.first; curr; curr = curr->next) {
if (curr->op == CLOSURE_CREATE) {
- struct bytecode* subfn = malloc(sizeof(struct bytecode));
+ struct bytecode* subfn = jv_mem_alloc(sizeof(struct bytecode));
bc->subfunctions[curr->imm.intval] = subfn;
subfn->globals = bc->globals;
subfn->parent = bc;
bc->subfunctions = 0;
}
bc->codelen = pos;
- uint16_t* code = malloc(sizeof(uint16_t) * bc->codelen);
+ uint16_t* code = jv_mem_alloc(sizeof(uint16_t) * bc->codelen);
bc->code = code;
pos = 0;
jv constant_pool = jv_array();
}
int block_compile(block b, struct locfile* locations, struct bytecode** out) {
- struct bytecode* bc = malloc(sizeof(struct bytecode));
+ struct bytecode* bc = jv_mem_alloc(sizeof(struct bytecode));
bc->parent = 0;
bc->nclosures = 0;
- bc->globals = malloc(sizeof(struct symbol_table));
+ bc->globals = jv_mem_alloc(sizeof(struct symbol_table));
int ncfunc = count_cfunctions(b);
bc->globals->ncfunctions = 0;
- bc->globals->cfunctions = malloc(sizeof(struct cfunction) * ncfunc);
+ bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc);
int nerrors = compile(locations, bc, b);
assert(bc->globals->ncfunctions == ncfunc);
if (nerrors > 0) {
#include "forkable_stack.h"
#include "frame_layout.h"
+#include "jv_alloc.h"
#include "locfile.h"
#include "jv.h"
#include "jv_aux.h"
if (pos == pathsize) {
int oldpathsize = pathsize;
pathsize = oldpathsize ? oldpathsize * 2 : 100;
- pathbuf = realloc(pathbuf, sizeof(pathbuf[0]) * pathsize);
+ pathbuf = jv_mem_realloc(pathbuf, sizeof(pathbuf[0]) * pathsize);
for (int i=oldpathsize; i<pathsize; i++) {
pathbuf[i] = jv_invalid();
}
for (int i=0; i<pathsize; i++) {
jv_free(pathbuf[i]);
}
- free(pathbuf);
+ jv_mem_free(pathbuf);
pathbuf = 0;
pathsize = 0;
}
#ifndef FORKABLE_STACK_H
#define FORKABLE_STACK_H
-#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#include <string.h>
+#include "jv_alloc.h"
struct forkable_stack_header {
/* distance in bytes between this header and the header
char* stk;
// stk+length is just past end of allocated area
- // stk = malloc(length)
+ // stk = jv_mem_alloc(length)
int length;
// stk+pos is header of top object, or stk+length if empty
}
static void forkable_stack_init(struct forkable_stack* s, size_t sz) {
- s->stk = malloc(sz);
+ s->stk = jv_mem_alloc(sz);
s->length = sz;
s->pos = s->length;
s->savedlimit = s->length;
static void forkable_stack_free(struct forkable_stack* s) {
assert(forkable_stack_empty(s));
assert(s->savedlimit == s->length);
- free(s->stk);
+ jv_mem_free(s->stk);
s->stk = 0;
}
if (curr - size < 0) {
int oldlen = s->length;
s->length = (size + oldlen + 1024) * 2;
- s->stk = realloc(s->stk, s->length);
+ s->stk = jv_mem_realloc(s->stk, s->length);
int shift = s->length - oldlen;
memmove(s->stk + shift, s->stk, oldlen);
s->pos += shift;
#include <string.h>
#include <stdarg.h>
+#include "jv_alloc.h"
#include "jv.h"
/*
jv x;
x.kind = JV_KIND_INVALID;
x.val.complex.i[0] = x.val.complex.i[1] = 0;
- jvp_invalid* i = malloc(sizeof(jvp_invalid));
+ jvp_invalid* i = jv_mem_alloc(sizeof(jvp_invalid));
x.val.complex.ptr = &i->refcnt;
i->refcnt.count = 1;
i->errmsg = err;
static void jvp_invalid_free(jv_complex* x) {
if (jvp_refcnt_dec(x)) {
jv_free(((jvp_invalid*)x->ptr)->errmsg);
- free(x->ptr);
+ jv_mem_free(x->ptr);
}
}
}
static jvp_array* jvp_array_alloc(unsigned size) {
- jvp_array* a = malloc(sizeof(jvp_array) + sizeof(jv) * size);
+ jvp_array* a = jv_mem_alloc(sizeof(jvp_array) + sizeof(jv) * size);
a->refcnt.count = 1;
a->length = 0;
a->alloc_length = size;
for (int i=0; i<array->length; i++) {
jv_free(array->elements[i]);
}
- free(array);
+ jv_mem_free(array);
}
}
}
static jvp_string* jvp_string_alloc(uint32_t size) {
- jvp_string* s = malloc(sizeof(jvp_string) + size + 1);
+ jvp_string* s = jv_mem_alloc(sizeof(jvp_string) + size + 1);
s->refcnt.count = 1;
s->alloc_length = size;
return s;
static void jvp_string_free(jv_complex* s) {
if (jvp_refcnt_dec(s)) {
jvp_string* str = jvp_string_ptr(s);
- free(str);
+ jv_mem_free(str);
}
}
jv jv_string_fmt(const char* fmt, ...) {
int size = 1024;
while (1) {
- char* buf = malloc(size);
+ char* buf = jv_mem_alloc(size);
va_list args;
va_start(args, fmt);
int n = vsnprintf(buf, size, fmt, args);
va_end(args);
if (n < size) {
jv ret = jv_string_sized(buf, n);
- free(buf);
+ jv_mem_free(buf);
return ret;
} else {
- free(buf);
+ jv_mem_free(buf);
size = n * 2;
}
}
// size must be a power of two
assert(size > 0 && (size & (size - 1)) == 0);
- jvp_object* obj = malloc(sizeof(jvp_object) +
- sizeof(struct object_slot) * size +
- sizeof(int) * (size * 2));
+ jvp_object* obj = jv_mem_alloc(sizeof(jvp_object) +
+ sizeof(struct object_slot) * size +
+ sizeof(int) * (size * 2));
obj->refcnt.count = 1;
for (int i=0; i<size; i++) {
obj->elements[i].next = i - 1;
jv_free(slot->value);
}
}
- free(jvp_object_ptr(o));
+ jv_mem_free(jvp_object_ptr(o));
}
}
new_slot->value = slot->value;
}
// references are transported, just drop the old table
- free(jvp_object_ptr(object));
+ jv_mem_free(jvp_object_ptr(object));
*object = new_object;
}
jv_free(a);
jv_free(b);
return r;
-}
\ No newline at end of file
+}
--- /dev/null
+#include <stdlib.h>
+#include "jv_alloc.h"
+
+
+void* jv_mem_alloc(size_t sz) {
+ return malloc(sz);
+}
+
+void jv_mem_free(void* p) {
+ free(p);
+}
+
+void* jv_mem_realloc(void* p, size_t sz) {
+ return realloc(p, sz);
+}
--- /dev/null
+#ifndef JV_ALLOC_H
+#define JV_ALLOC_H
+
+#include <stddef.h>
+
+void* jv_mem_alloc(size_t);
+void jv_mem_free(void*);
+__attribute__((warn_unused_result)) void* jv_mem_realloc(void*, size_t);
+
+#endif
#include "jv_aux.h"
#include <string.h>
#include <stdlib.h>
+#include "jv_alloc.h"
jv jv_lookup(jv t, jv k) {
jv v;
jv jv_keys(jv x) {
if (jv_get_kind(x) == JV_KIND_OBJECT) {
int nkeys = jv_object_length(jv_copy(x));
- jv* keys = malloc(sizeof(jv) * nkeys);
+ jv* keys = jv_mem_alloc(sizeof(jv) * nkeys);
int kidx = 0;
jv_object_foreach(i, x) {
keys[kidx++] = jv_object_iter_key(x, i);
for (int i = 0; i<nkeys; i++) {
answer = jv_array_append(answer, keys[i]);
}
- free(keys);
+ jv_mem_free(keys);
jv_free(x);
return answer;
} else if (jv_get_kind(x) == JV_KIND_ARRAY) {
assert(jv_get_kind(keys) == JV_KIND_ARRAY);
assert(jv_array_length(jv_copy(objects)) == jv_array_length(jv_copy(keys)));
int n = jv_array_length(jv_copy(objects));
- struct sort_entry* entries = malloc(sizeof(struct sort_entry) * n);
+ struct sort_entry* entries = jv_mem_alloc(sizeof(struct sort_entry) * n);
for (int i=0; i<n; i++) {
entries[i].object = jv_array_get(jv_copy(objects), i);
entries[i].key = jv_array_get(jv_copy(keys), i);
jv_free(entries[i].key);
ret = jv_array_set(ret, i, entries[i].object);
}
- free(entries);
+ jv_mem_free(entries);
return ret;
}
}
jv_free(curr_key);
ret = jv_array_append(ret, group);
- free(entries);
+ jv_mem_free(entries);
return ret;
}
#include "jv_dtoa.h"
+#include "jv_alloc.h"
+#define MALLOC jv_mem_alloc
+#define FREE jv_mem_free
+
+
#ifndef Long
#define Long long
while (C->freelist[k]) {
Bigint* v = C->freelist[k];
C->freelist[k] = v->next;
- free(v);
+ FREE(v);
}
}
}
#include "jv_dtoa.h"
#include "jv_parse.h"
#include "jv_unicode.h"
+#include "jv_alloc.h"
typedef const char* presult;
jv_free(p->next);
for (int i=0; i<p->stackpos; i++)
jv_free(p->stack[i]);
- free(p->stack);
- free(p->tokenbuf);
+ jv_mem_free(p->stack);
+ jv_mem_free(p->tokenbuf);
jvp_dtoa_context_free(&p->dtoa);
}
assert(p->stackpos <= p->stacklen);
if (p->stackpos == p->stacklen) {
p->stacklen = p->stacklen * 2 + 10;
- p->stack = realloc(p->stack, p->stacklen * sizeof(jv));
+ p->stack = jv_mem_realloc(p->stack, p->stacklen * sizeof(jv));
}
assert(p->stackpos < p->stacklen);
p->stack[p->stackpos++] = v;
assert(p->tokenpos <= p->tokenlen);
if (p->tokenpos == p->tokenlen) {
p->tokenlen = p->tokenlen*2 + 256;
- p->tokenbuf = realloc(p->tokenbuf, p->tokenlen);
+ p->tokenbuf = jv_mem_realloc(p->tokenbuf, p->tokenlen);
}
assert(p->tokenpos < p->tokenlen);
p->tokenbuf[p->tokenpos++] = c;
%{
+#include "jv_alloc.h"
#include "compile.h"
struct lexer_param;
%}
%option noyywrap nounput noinput nodefault
+%option noyyalloc noyyrealloc noyyfree
%option reentrant
%option extra-type="int"
%option bison-bridge bison-locations
yy_push_state(state, yyscanner);
return c;
}
+
+void* yyalloc(size_t sz, void* extra) {
+ return jv_mem_alloc(sz);
+}
+void* yyrealloc(void* p, size_t sz, void* extra) {
+ return jv_mem_realloc(p, sz);
+}
+void yyfree(void* p, void* extra) {
+ jv_mem_free(p);
+}
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
+#include "jv_alloc.h"
typedef struct {
int start, end;
} location;
for (int i=0; i<length; i++) {
if (data[i] == '\n') l->nlines++;
}
- l->linemap = malloc(sizeof(int) * (l->nlines + 1));
+ l->linemap = jv_mem_alloc(sizeof(int) * (l->nlines + 1));
l->linemap[0] = 0;
int line = 1;
for (int i=0; i<length; i++) {
}
static void locfile_free(struct locfile* l) {
- free(l->linemap);
+ jv_mem_free(l->linemap);
}
static int locfile_get_line(struct locfile* l, int pos) {
+#define _POSIX_SOURCE
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "locfile.h"
#include "parser.h"
#include "execute.h"
+#include "jv_alloc.h"
#include "version.gen.h"
static const char* progname;
if (argc) progname = argv[0];
const char* program = 0;
- input_filenames = malloc(sizeof(const char*) * argc);
+ input_filenames = jv_mem_alloc(sizeof(const char*) * argc);
ninput_files = 0;
int further_args_are_files = 0;
for (int i=1; i<argc; i++) {
process(slurped);
}
}
- free(input_filenames);
+ jv_mem_free(input_filenames);
bytecode_free(bc);
return 0;
}
#include <stdio.h>
#include <string.h>
#include "compile.h"
+#include "jv_alloc.h"
+#define YYMALLOC jv_mem_alloc
+#define YYFREE jv_mem_free
struct lexer_param;