xvect.h is now based on kvec.h

This commit is contained in:
Yuichi Nishiwaki 2015-01-22 22:15:12 +09:00
parent 9af074d803
commit f7d506cd35
3 changed files with 124 additions and 266 deletions

View File

@ -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(&regs, 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(&regs, *var, &n);
xh_put_ptr(&regs, 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(&regs, *var, &n);
xh_put_ptr(&regs, 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(&regs, *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(&regs, 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++;

View File

@ -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);

View File

@ -1,202 +1,76 @@
#ifndef XVECT_H__
#define XVECT_H__
/*
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idylls.jp>
*/
/* The MIT License
#if defined(__cplusplus)
extern "C" {
#endif
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
Copyright (c) 2014, by Yuichi Nishiwaki <yuichi@idylls.jp>
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