From f7d506cd359af14e8b99b5d7b55897dc6526cdff Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Thu, 22 Jan 2015 22:15:12 +0900 Subject: [PATCH] xvect.h is now based on kvec.h --- extlib/benz/codegen.c | 136 +++++++--------- extlib/benz/gc.c | 10 +- extlib/benz/include/picrin/xvect.h | 244 +++++++---------------------- 3 files changed, 124 insertions(+), 266 deletions(-) diff --git a/extlib/benz/codegen.c b/extlib/benz/codegen.c index c0d87419..63f3ab87 100644 --- a/extlib/benz/codegen.c +++ b/extlib/benz/codegen.c @@ -17,6 +17,10 @@ # error enable PIC_NONE_IS_FALSE #endif +typedef xvect_t(pic_sym *) xvect; + +#define xv_push_sym(v, x) xv_push(pic_sym *, (v), (x)) + /** * scope object */ @@ -94,7 +98,7 @@ new_analyze_state(pic_state *pic) push_scope(state, pic_nil_value()); pic_dict_for_each (sym, pic->globals, it) { - xv_push(&state->scope->locals, &sym); + xv_push_sym(state->scope->locals, sym); } return state; @@ -119,7 +123,7 @@ analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect * return false; } sym = pic_sym_ptr(t); - xv_push(args, &sym); + xv_push_sym(*args, sym); } if (pic_nil_p(v)) { *varg = false; @@ -127,7 +131,7 @@ analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect * else if (pic_sym_p(v)) { *varg = true; sym = pic_sym_ptr(v); - xv_push(locals, &sym); + xv_push_sym(*locals, sym); } else { return false; @@ -144,9 +148,9 @@ push_scope(analyze_state *state, pic_value formals) bool varg; xvect args, locals, captures; - xv_init(&args, sizeof(pic_sym *)); - xv_init(&locals, sizeof(pic_sym *)); - xv_init(&captures, sizeof(pic_sym *)); + xv_init(args); + xv_init(locals); + xv_init(captures); if (analyze_args(pic, formals, &varg, &args, &locals)) { scope = pic_alloc(pic, sizeof(analyze_scope)); @@ -163,8 +167,8 @@ push_scope(analyze_state *state, pic_value formals) return true; } else { - xv_destroy(&args); - xv_destroy(&locals); + xv_destroy(args); + xv_destroy(locals); return false; } } @@ -172,12 +176,13 @@ push_scope(analyze_state *state, pic_value formals) static void pop_scope(analyze_state *state) { + pic_state *pic = state->pic; analyze_scope *scope; scope = state->scope; - xv_destroy(&scope->args); - xv_destroy(&scope->locals); - xv_destroy(&scope->captures); + xv_destroy(scope->args); + xv_destroy(scope->locals); + xv_destroy(scope->captures); scope = scope->up; pic_free(state->pic, state->scope); @@ -187,38 +192,33 @@ pop_scope(analyze_state *state) static bool lookup_scope(analyze_scope *scope, pic_sym *sym) { - pic_sym **arg, **local; size_t i; /* args */ - for (i = 0; i < xv_size(&scope->args); ++i) { - arg = xv_get(&scope->args, i); - if (*arg == sym) + for (i = 0; i < xv_size(scope->args); ++i) { + if (xv_A(scope->args, i) == sym) return true; } /* locals */ - for (i = 0; i < xv_size(&scope->locals); ++i) { - local = xv_get(&scope->locals, i); - if (*local == sym) + for (i = 0; i < xv_size(scope->locals); ++i) { + if (xv_A(scope->locals, i) == sym) return true; } return false; } static void -capture_var(analyze_scope *scope, pic_sym *sym) +capture_var(pic_state *pic, analyze_scope *scope, pic_sym *sym) { - pic_sym **var; size_t i; - for (i = 0; i < xv_size(&scope->captures); ++i) { - var = xv_get(&scope->captures, i); - if (*var == sym) { + for (i = 0; i < xv_size(scope->captures); ++i) { + if (xv_A(scope->captures, i) == sym) { break; } } - if (i == xv_size(&scope->captures)) { - xv_push(&scope->captures, &sym); + if (i == xv_size(scope->captures)) { + xv_push_sym(scope->captures, sym); } } @@ -231,7 +231,7 @@ find_var(analyze_state *state, pic_sym *sym) while (scope) { if (lookup_scope(scope, sym)) { if (depth > 0) { - capture_var(scope, sym); + capture_var(state->pic, scope, sym); } return depth; } @@ -252,7 +252,7 @@ define_var(analyze_state *state, pic_sym *sym) return; } - xv_push(&scope->locals, &sym); + xv_push_sym(scope->locals, sym); } static pic_value analyze_node(analyze_state *, pic_value, bool); @@ -373,13 +373,11 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v if (push_scope(state, formals)) { analyze_scope *scope = state->scope; - pic_sym **var; size_t i; args = pic_nil_value(); - for (i = xv_size(&scope->args); i > 0; --i) { - var = xv_get(&scope->args, i - 1); - pic_push(pic, pic_obj_value(*var), args); + for (i = xv_size(scope->args); i > 0; --i) { + pic_push(pic, pic_obj_value(xv_A(scope->args, i - 1)), args); } varg = scope->varg @@ -392,15 +390,13 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v analyze_deferred(state); locals = pic_nil_value(); - for (i = xv_size(&scope->locals); i > 0; --i) { - var = xv_get(&scope->locals, i - 1); - pic_push(pic, pic_obj_value(*var), locals); + for (i = xv_size(scope->locals); i > 0; --i) { + pic_push(pic, pic_obj_value(xv_A(scope->locals, i - 1)), locals); } captures = pic_nil_value(); - for (i = xv_size(&scope->captures); i > 0; --i) { - var = xv_get(&scope->captures, i - 1); - pic_push(pic, pic_obj_value(*var), captures); + for (i = xv_size(scope->captures); i > 0; --i) { + pic_push(pic, pic_obj_value(xv_A(scope->captures, i - 1)), captures); } pop_scope(state); @@ -925,27 +921,24 @@ create_activation(codegen_context *cxt) { size_t i, n; xhash regs; - pic_sym **var; size_t offset; xh_init_ptr(®s, sizeof(size_t)); offset = 1; - for (i = 0; i < xv_size(&cxt->args); ++i) { - var = xv_get(&cxt->args, i); + for (i = 0; i < xv_size(cxt->args); ++i) { n = i + offset; - xh_put_ptr(®s, *var, &n); + xh_put_ptr(®s, xv_A(cxt->args, i), &n); } offset += i; - for (i = 0; i < xv_size(&cxt->locals); ++i) { - var = xv_get(&cxt->locals, i); + for (i = 0; i < xv_size(cxt->locals); ++i) { n = i + offset; - xh_put_ptr(®s, *var, &n); + xh_put_ptr(®s, xv_A(cxt->locals, i), &n); } - for (i = 0; i < xv_size(&cxt->captures); ++i) { - var = xv_get(&cxt->captures, i); - if ((n = xh_val(xh_get_ptr(®s, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) { + for (i = 0; i < xv_size(cxt->captures); ++i) { + n = xh_val(xh_get_ptr(®s, xv_A(cxt->captures, i)), size_t); + if (n <= xv_size(cxt->args) || (cxt->varg && n == xv_size(cxt->args) + 1)) { /* copy arguments to capture variable area */ cxt->code[cxt->clen].insn = OP_LREF; cxt->code[cxt->clen].u.i = (int)n; @@ -966,7 +959,6 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v pic_state *pic = state->pic; codegen_context *cxt; pic_value var, it; - pic_sym *sym; assert(pic_sym_p(name) || pic_false_p(name)); @@ -977,21 +969,18 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v : pic_sym_ptr(name); cxt->varg = varg; - xv_init(&cxt->args, sizeof(pic_sym *)); - xv_init(&cxt->locals, sizeof(pic_sym *)); - xv_init(&cxt->captures, sizeof(pic_sym *)); + xv_init(cxt->args); + xv_init(cxt->locals); + xv_init(cxt->captures); pic_for_each (var, args, it) { - sym = pic_sym_ptr(var); - xv_push(&cxt->args, &sym); + xv_push_sym(cxt->args, pic_sym_ptr(var)); } pic_for_each (var, locals, it) { - sym = pic_sym_ptr(var); - xv_push(&cxt->locals, &sym); + xv_push_sym(cxt->locals, pic_sym_ptr(var)); } pic_for_each (var, captures, it) { - sym = pic_sym_ptr(var); - xv_push(&cxt->captures, &sym); + xv_push_sym(cxt->captures, pic_sym_ptr(var)); } cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code)); @@ -1026,9 +1015,9 @@ pop_codegen_context(codegen_state *state) irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP); irep->name = state->cxt->name; irep->varg = state->cxt->varg; - irep->argc = (int)xv_size(&state->cxt->args) + 1; - irep->localc = (int)xv_size(&state->cxt->locals); - irep->capturec = (int)xv_size(&state->cxt->captures); + irep->argc = (int)xv_size(state->cxt->args) + 1; + irep->localc = (int)xv_size(state->cxt->locals); + irep->capturec = (int)xv_size(state->cxt->captures); irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen); irep->clen = state->cxt->clen; irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen); @@ -1039,9 +1028,9 @@ pop_codegen_context(codegen_state *state) irep->slen = state->cxt->slen; /* finalize */ - xv_destroy(&cxt->args); - xv_destroy(&cxt->locals); - xv_destroy(&cxt->captures); + xv_destroy(cxt->args); + xv_destroy(cxt->locals); + xv_destroy(cxt->captures); /* destroy context */ cxt = cxt->up; @@ -1056,15 +1045,13 @@ index_capture(codegen_state *state, pic_sym *sym, int depth) { codegen_context *cxt = state->cxt; size_t i; - pic_sym **var; while (depth-- > 0) { cxt = cxt->up; } - for (i = 0; i < xv_size(&cxt->captures); ++i) { - var = xv_get(&cxt->captures, i); - if (*var == sym) + for (i = 0; i < xv_size(cxt->captures); ++i) { + if (xv_A(cxt->captures, i) == sym) return (int)i; } return -1; @@ -1075,18 +1062,15 @@ index_local(codegen_state *state, pic_sym *sym) { codegen_context *cxt = state->cxt; size_t i, offset; - pic_sym **var; offset = 1; - for (i = 0; i < xv_size(&cxt->args); ++i) { - var = xv_get(&cxt->args, i); - if (*var == sym) + for (i = 0; i < xv_size(cxt->args); ++i) { + if (xv_A(cxt->args, i) == sym) return (int)(i + offset); } offset += i; - for (i = 0; i < xv_size(&cxt->locals); ++i) { - var = xv_get(&cxt->locals, i); - if (*var == sym) + for (i = 0; i < xv_size(cxt->locals); ++i) { + if (xv_A(cxt->locals, i) == sym) return (int)(i + offset); } return -1; @@ -1145,7 +1129,7 @@ codegen(codegen_state *state, pic_value obj) name = pic_sym_ptr(pic_list_ref(pic, obj, 1)); if ((i = index_capture(state, name, 0)) != -1) { cxt->code[cxt->clen].insn = OP_LREF; - cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1; + cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1; cxt->clen++; return; } @@ -1191,7 +1175,7 @@ codegen(codegen_state *state, pic_value obj) name = pic_sym_ptr(pic_list_ref(pic, var, 1)); if ((i = index_capture(state, name, 0)) != -1) { cxt->code[cxt->clen].insn = OP_LSET; - cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1; + cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1; cxt->clen++; cxt->code[cxt->clen].insn = OP_PUSHNONE; cxt->clen++; diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 2fc69b74..6dc2be85 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -704,20 +704,20 @@ static void gc_sweep_symbols(pic_state *pic) { xh_entry *it; - xvect xv; + xvect_t(xh_entry *) xv; size_t i; char *cstr; - xv_init(&xv, sizeof(xh_entry *)); + xv_init(xv); for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { if (! gc_obj_is_marked((struct pic_object *)xh_val(it, pic_sym *))) { - xv_push(&xv, &it); + xv_push(xh_entry *, xv, it); } } - for (i = 0; i < xv_size(&xv); ++i) { - cstr = xh_key(*(xh_entry **)xv_get(&xv, i), char *); + for (i = 0; i < xv_size(xv); ++i) { + cstr = xh_key(xv_A(xv, i), char *); xh_del_str(&pic->syms, cstr); diff --git a/extlib/benz/include/picrin/xvect.h b/extlib/benz/include/picrin/xvect.h index a04d227a..6dcabb1c 100644 --- a/extlib/benz/include/picrin/xvect.h +++ b/extlib/benz/include/picrin/xvect.h @@ -1,202 +1,76 @@ #ifndef XVECT_H__ #define XVECT_H__ -/* - * Copyright (c) 2014 by Yuichi Nishiwaki - */ +/* The MIT License -#if defined(__cplusplus) -extern "C" { -#endif + Copyright (c) 2008, by Attractive Chaos + Copyright (c) 2014, by Yuichi Nishiwaki -typedef struct xvect { - char *data; - size_t size, mask, head, tail, width; -} xvect; + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: -static inline void xv_init(xvect *, size_t); -static inline void xv_destroy(xvect *); + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. -static inline size_t xv_size(xvect *); + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ -static inline void xv_reserve(xvect *, size_t); -static inline void xv_shrink(xvect *, size_t); +#define xv_realloc(P,Z) pic_realloc(pic,P,Z) +#define xv_free(P) pic_free(pic,P) -static inline void *xv_get(xvect *, size_t); -static inline void xv_set(xvect *, size_t, void *); +#define xv_roundup32(x) \ + (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -static inline void xv_push(xvect *, void *); -static inline void *xv_pop(xvect *); +#define xvect_t(type) struct { size_t n, m; type *a; } +#define xv_init(v) ((v).n = (v).m = 0, (v).a = 0) +#define xv_destroy(v) xv_free((v).a) +#define xv_A(v, i) ((v).a[(i)]) +#define xv_pop(v) ((v).a[--(v).n]) +#define xv_size(v) ((v).n) +#define xv_max(v) ((v).m) -static inline void *xv_shift(xvect *); -static inline void xv_unshift(xvect *, void *); +#define xv_resize(type, v, s) \ + ((v).m = (s), (v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m)) -static inline void xv_splice(xvect *, size_t, size_t); -static inline void xv_insert(xvect *, size_t, void *); +#define xv_copy(type, v1, v0) \ + do { \ + if ((v1).m < (v0).n) xv_resize(type, v1, (v0).n); \ + (v1).n = (v0).n; \ + memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ + } while (0) \ -static inline void -xv_init(xvect *x, size_t width) -{ - x->data = NULL; - x->width = width; - x->size = 0; - x->mask = (size_t)-1; - x->head = 0; - x->tail = 0; -} +#define xv_push(type, v, x) \ + do { \ + if ((v).n == (v).m) { \ + (v).m = (v).m? (v).m<<1 : 2; \ + (v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m); \ + } \ + (v).a[(v).n++] = (x); \ + } while (0) -static inline void -xv_destroy(xvect *x) -{ - free(x->data); -} +#define xv_pushp(type, v) \ + (((v).n == (v).m)? \ + ((v).m = ((v).m? (v).m<<1 : 2), \ + (v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m), 0) \ + : 0), ((v).a + ((v).n++)) -static inline size_t -xv_size(xvect *x) -{ - return x->tail < x->head - ? x->tail + x->size - x->head - : x->tail - x->head; -} - -static inline size_t -xv_round2(size_t x) -{ - x -= 1; - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - x |= (x >> 32); - x++; - return x; -} - -static inline void -xv_rotate(xvect *x) -{ - if (x->tail < x->head) { - char buf[x->size * x->width]; - - /* perform rotation */ - memcpy(buf, x->data, sizeof buf); - memcpy(x->data, buf + x->head * x->width, (x->size - x->head) * x->width); - memcpy(x->data + (x->size - x->head) * x->width, buf, x->tail * x->width); - x->tail = x->size - x->head + x->tail; - x->head = 0; - } -} - -static inline void -xv_adjust(xvect *x, size_t size) -{ - size = xv_round2(size); - if (size != x->size) { - xv_rotate(x); - x->data = realloc(x->data, size * x->width); - x->size = size; - x->mask = size - 1; - } -} - -static inline void -xv_reserve(xvect *x, size_t mincapa) -{ - if (x->size < mincapa + 1) { - xv_adjust(x, mincapa + 1); /* capa == size - 1 */ - } -} - -static inline void -xv_shrink(xvect *x, size_t maxcapa) -{ - if (x->size > maxcapa + 1) { - xv_adjust(x, maxcapa + 1); /* capa == size - 1 */ - } -} - -static inline void * -xv_get(xvect *x, size_t i) -{ - assert(i < xv_size(x)); - - return x->data + ((x->head + i) & x->mask) * x->width; -} - -static inline void -xv_set(xvect *x, size_t i, void *src) -{ - memcpy(xv_get(x, i), src, x->width); -} - -static inline void -xv_push(xvect *x, void *src) -{ - xv_reserve(x, xv_size(x) + 1); - x->tail = (x->tail + 1) & x->mask; - xv_set(x, xv_size(x) - 1, src); -} - -static inline void * -xv_pop(xvect *x) -{ - void *dat; - - assert(xv_size(x) >= 1); - - dat = xv_get(x, xv_size(x) - 1); - x->tail = (x->tail - 1) & x->mask; - return dat; -} - -static inline void * -xv_shift(xvect *x) -{ - void *dat; - - assert(xv_size(x) >= 1); - - dat = xv_get(x, 0); - x->head = (x->head + 1) & x->mask; - return dat; -} - -static inline void -xv_unshift(xvect *x, void *src) -{ - xv_reserve(x, xv_size(x) + 1); - x->head = (x->head - 1) & x->mask; - xv_set(x, 0, src); -} - -static inline void -xv_splice(xvect *x, size_t i, size_t j) -{ - assert(i <= j && j < xv_size(x)); - - xv_rotate(x); - memmove(xv_get(x, i), xv_get(x, j), (xv_size(x) - j) * x->width); - x->tail = (x->tail - j + i) & x->mask; -} - -static inline void -xv_insert(xvect *x, size_t i, void *src) -{ - assert(i <= xv_size(x)); - - xv_reserve(x, xv_size(x) + 1); - xv_rotate(x); - x->tail = (x->tail + 1) & x->mask; - - if (xv_size(x) - 1 != i) { - memmove(xv_get(x, i + 1), xv_get(x, i), (xv_size(x) - 1 - i) * x->width); - } - xv_set(x, i, src); -} - -#if defined(__cplusplus) -} -#endif +#define xv_a(type, v, i) \ + (((v).m <= (size_t)(i)? \ + ((v).m = (v).n = (i) + 1, xv_roundup32((v).m), \ + (v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m), 0) \ + : (v).n <= (size_t)(i)? (v).n = (i) + 1 \ + : 0), (v).a[(i)]) #endif