mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 17:27:18 +00:00
Change object implementaion to use open hashing. Currently
using simple linear probing.
This commit is contained in:
parent
e90b66af58
commit
f456de5fac
@ -918,21 +918,18 @@ static Slot compile_object(GstCompiler *c, FormOptions opts, GstObject *obj) {
|
|||||||
GstScope *scope = c->tail;
|
GstScope *scope = c->tail;
|
||||||
FormOptions subOpts = form_options_default();
|
FormOptions subOpts = form_options_default();
|
||||||
GstBuffer *buffer = c->buffer;
|
GstBuffer *buffer = c->buffer;
|
||||||
GstBucket *bucket;
|
|
||||||
Slot ret;
|
Slot ret;
|
||||||
SlotTracker tracker;
|
SlotTracker tracker;
|
||||||
uint32_t i, cap;
|
uint32_t i, cap;
|
||||||
cap = obj->capacity;
|
cap = obj->capacity;
|
||||||
ret = compiler_get_target(c, opts);
|
ret = compiler_get_target(c, opts);
|
||||||
tracker_init(c, &tracker);
|
tracker_init(c, &tracker);
|
||||||
for (i = 0; i < cap; ++i) {
|
for (i = 0; i < cap; i += 2) {
|
||||||
bucket = obj->buckets[i];
|
if (obj->data[i].type != GST_NIL) {
|
||||||
while (bucket != NULL) {
|
Slot slot = compile_value(c, subOpts, obj->data[i]);
|
||||||
Slot slot = compile_value(c, subOpts, bucket->key);
|
|
||||||
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
|
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
|
||||||
slot = compile_value(c, subOpts, bucket->value);
|
slot = compile_value(c, subOpts, obj->data[i + 1]);
|
||||||
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
|
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compiler_tracker_free(c, scope, &tracker);
|
compiler_tracker_free(c, scope, &tracker);
|
||||||
@ -1034,15 +1031,10 @@ void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) {
|
|||||||
/* Add many global variables */
|
/* Add many global variables */
|
||||||
void gst_compiler_globals(GstCompiler *c, GstObject *env) {
|
void gst_compiler_globals(GstCompiler *c, GstObject *env) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
GstBucket *bucket;
|
for (i = 0; i < env->capacity; i += 2) {
|
||||||
for (i = 0; i < env->capacity; ++i) {
|
if (env->data[i].type == GST_STRING) {
|
||||||
bucket = env->buckets[i];
|
compiler_declare_symbol(c, c->tail, env->data[i]);
|
||||||
while (bucket) {
|
gst_array_push(c->vm, c->env, env->data[i + 1]);
|
||||||
if (bucket->key.type == GST_STRING) {
|
|
||||||
compiler_declare_symbol(c, c->tail, bucket->key);
|
|
||||||
gst_array_push(c->vm, c->env, bucket->value);
|
|
||||||
}
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
165
core/ds.c
165
core/ds.c
@ -153,50 +153,60 @@ void *gst_userdata(Gst *vm, uint32_t size, GstObject *meta) {
|
|||||||
/* Create a new dictionary */
|
/* Create a new dictionary */
|
||||||
GstObject* gst_object(Gst *vm, uint32_t capacity) {
|
GstObject* gst_object(Gst *vm, uint32_t capacity) {
|
||||||
GstObject *o = gst_alloc(vm, sizeof(GstObject));
|
GstObject *o = gst_alloc(vm, sizeof(GstObject));
|
||||||
GstBucket **buckets = gst_zalloc(vm, capacity * sizeof(GstBucket *));
|
GstValue *data = gst_zalloc(vm, capacity * sizeof(GstValue));
|
||||||
o->buckets = buckets;
|
o->data = data;
|
||||||
o->capacity = capacity;
|
o->capacity = capacity;
|
||||||
o->count = 0;
|
o->count = 0;
|
||||||
o->parent = NULL;
|
o->parent = NULL;
|
||||||
|
o->deleted = 0;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find the bucket that contains the given key. Will also return
|
||||||
|
* bucket where key should go if not in object. */
|
||||||
|
static GstValue *gst_object_find(GstObject *o, GstValue key) {
|
||||||
|
uint32_t index = (gst_hash(key) % (o->capacity / 2)) * 2;
|
||||||
|
uint32_t i, j;
|
||||||
|
uint32_t start[2], end[2];
|
||||||
|
start[0] = index; end[0] = o->capacity;
|
||||||
|
start[1] = 0; end[1] = index;
|
||||||
|
for (j = 0; j < 2; ++j)
|
||||||
|
for (i = start[j]; i < end[j]; i += 2) {
|
||||||
|
if (o->data[i].type == GST_NIL) {
|
||||||
|
if (o->data[i + 1].type == GST_NIL) {
|
||||||
|
/* Empty */
|
||||||
|
return o->data + i;
|
||||||
|
}
|
||||||
|
} else if (gst_equals(o->data[i], key)) {
|
||||||
|
return o->data + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Resize the dictionary table. */
|
/* Resize the dictionary table. */
|
||||||
static void gst_object_rehash(Gst *vm, GstObject *o, uint32_t size) {
|
static void gst_object_rehash(Gst *vm, GstObject *o, uint32_t size) {
|
||||||
GstBucket **newBuckets = gst_zalloc(vm, size * sizeof(GstBucket *));
|
GstValue *olddata = o->data;
|
||||||
uint32_t i, count;
|
GstValue *newdata = gst_zalloc(vm, size * sizeof(GstValue));
|
||||||
for (i = 0, count = o->capacity; i < count; ++i) {
|
uint32_t i, oldcapacity;
|
||||||
GstBucket *bucket = o->buckets[i];
|
oldcapacity = o->capacity;
|
||||||
while (bucket) {
|
o->data = newdata;
|
||||||
uint32_t index;
|
o->capacity = size;
|
||||||
GstBucket *next = bucket->next;
|
o->deleted = 0;
|
||||||
index = gst_hash(bucket->key) % size;
|
for (i = 0; i < oldcapacity; i += 2) {
|
||||||
bucket->next = newBuckets[index];
|
if (olddata[i].type != GST_NIL) {
|
||||||
newBuckets[index] = bucket;
|
GstValue *bucket = gst_object_find(o, olddata[i]);
|
||||||
bucket = next;
|
bucket[0] = olddata[i];
|
||||||
|
bucket[1] = olddata[i + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o->buckets = newBuckets;
|
|
||||||
o->capacity = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the bucket that contains the given key */
|
|
||||||
static GstBucket *gst_object_find(GstObject *o, GstValue key) {
|
|
||||||
uint32_t index = gst_hash(key) % o->capacity;
|
|
||||||
GstBucket *bucket = o->buckets[index];
|
|
||||||
while (bucket) {
|
|
||||||
if (gst_equals(bucket->key, key))
|
|
||||||
return bucket;
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
return (GstBucket *)0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a value out of the object */
|
/* Get a value out of the object */
|
||||||
GstValue gst_object_get(GstObject *o, GstValue key) {
|
GstValue gst_object_get(GstObject *o, GstValue key) {
|
||||||
GstBucket *bucket = gst_object_find(o, key);
|
GstValue *bucket = gst_object_find(o, key);
|
||||||
if (bucket) {
|
if (bucket && bucket[0].type != GST_NIL) {
|
||||||
return bucket->value;
|
return bucket[1];
|
||||||
} else {
|
} else {
|
||||||
GstValue nil;
|
GstValue nil;
|
||||||
nil.type = GST_NIL;
|
nil.type = GST_NIL;
|
||||||
@ -205,75 +215,60 @@ GstValue gst_object_get(GstObject *o, GstValue key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove an entry from the dictionary */
|
/* Remove an entry from the dictionary */
|
||||||
GstValue gst_object_remove(Gst * vm, GstObject *o, GstValue key) {
|
GstValue gst_object_remove(GstObject *o, GstValue key) {
|
||||||
GstBucket *bucket, *previous;
|
GstValue *bucket = gst_object_find(o, key);
|
||||||
uint32_t index = gst_hash(key) % o->capacity;
|
if (bucket && bucket[0].type != GST_NIL) {
|
||||||
bucket = o->buckets[index];
|
GstValue ret = bucket[1];
|
||||||
previous = (GstBucket *)0;
|
o->count--;
|
||||||
while (bucket) {
|
o->deleted++;
|
||||||
if (gst_equals(bucket->key, key)) {
|
bucket[0].type = GST_NIL;
|
||||||
if (previous) {
|
bucket[1].type = GST_BOOLEAN;
|
||||||
previous->next = bucket->next;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
o->buckets[index] = bucket->next;
|
|
||||||
}
|
|
||||||
if (o->count < o->capacity / 4) {
|
|
||||||
gst_object_rehash(vm, o, o->capacity / 2);
|
|
||||||
}
|
|
||||||
--o->count;
|
|
||||||
return bucket->value;
|
|
||||||
}
|
|
||||||
previous = bucket;
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
/* Return nil if we found nothing */
|
|
||||||
{
|
|
||||||
GstValue nil;
|
GstValue nil;
|
||||||
nil.type = GST_NIL;
|
nil.type = GST_NIL;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put a value into the dictionary. */
|
/* Put a value into the object */
|
||||||
void gst_object_put(Gst *vm, GstObject *o, GstValue key, GstValue value) {
|
void gst_object_put(Gst *vm, GstObject *o, GstValue key, GstValue value) {
|
||||||
GstBucket *bucket, *previous;
|
|
||||||
uint32_t index = gst_hash(key) % o->capacity;
|
|
||||||
if (key.type == GST_NIL) return;
|
if (key.type == GST_NIL) return;
|
||||||
/* Do a removal if value is nil */
|
|
||||||
if (value.type == GST_NIL) {
|
if (value.type == GST_NIL) {
|
||||||
bucket = o->buckets[index];
|
gst_object_remove(o, key);
|
||||||
previous = (GstBucket *)0;
|
|
||||||
while (bucket) {
|
|
||||||
if (gst_equals(bucket->key, key)) {
|
|
||||||
if (previous) {
|
|
||||||
previous->next = bucket->next;
|
|
||||||
} else {
|
|
||||||
o->buckets[index] = bucket->next;
|
|
||||||
}
|
|
||||||
if (o->count < o->capacity / 4) {
|
|
||||||
gst_object_rehash(vm, o, o->capacity / 2);
|
|
||||||
}
|
|
||||||
--o->count;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
previous = bucket;
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bucket = gst_object_find(o, key);
|
GstValue *bucket = gst_object_find(o, key);
|
||||||
if (bucket) {
|
if (bucket && bucket[0].type != GST_NIL) {
|
||||||
bucket->value = value;
|
bucket[1] = value;
|
||||||
} else {
|
} else {
|
||||||
if (o->count >= 2 * o->capacity) {
|
if (!bucket || 4 * (o->count + o->deleted) >= o->capacity) {
|
||||||
gst_object_rehash(vm, o, 2 * o->capacity);
|
gst_object_rehash(vm, o, 4 * o->count + 6);
|
||||||
}
|
}
|
||||||
bucket = gst_alloc(vm, sizeof(GstBucket));
|
bucket = gst_object_find(o, key);
|
||||||
bucket->next = o->buckets[index];
|
bucket[0] = key;
|
||||||
bucket->value = value;
|
bucket[1] = value;
|
||||||
bucket->key = key;
|
|
||||||
o->buckets[index] = bucket;
|
|
||||||
++o->count;
|
++o->count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find next key in an object. Returns nil if no next key. */
|
||||||
|
GstValue gst_object_next(GstObject *o, GstValue key) {
|
||||||
|
GstValue ret;
|
||||||
|
GstValue *bucket;
|
||||||
|
if (key.type == GST_NIL)
|
||||||
|
bucket = o->data - 2;
|
||||||
|
else
|
||||||
|
bucket = gst_object_find(o, key);
|
||||||
|
if (bucket && bucket[0].type != GST_NIL) {
|
||||||
|
GstValue *nextbucket, *end;
|
||||||
|
end = o->data + o->capacity;
|
||||||
|
for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) {
|
||||||
|
if (nextbucket[0].type != GST_NIL)
|
||||||
|
return nextbucket[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.type = GST_NIL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
14
core/gc.c
14
core/gc.c
@ -142,16 +142,12 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) {
|
|||||||
case GST_OBJECT:
|
case GST_OBJECT:
|
||||||
if (gc_header(x.object)->color != vm->black) {
|
if (gc_header(x.object)->color != vm->black) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
GstBucket *bucket;
|
|
||||||
gc_header(x.object)->color = vm->black;
|
gc_header(x.object)->color = vm->black;
|
||||||
gc_header(x.object->buckets)->color = vm->black;
|
gc_header(x.object->data)->color = vm->black;
|
||||||
for (i = 0; i < x.object->capacity; ++i) {
|
for (i = 0; i < x.object->capacity; i += 2) {
|
||||||
bucket = x.object->buckets[i];
|
if (x.object->data[i].type != GST_NIL) {
|
||||||
while (bucket) {
|
gst_mark_value(vm, x.object->data[i]);
|
||||||
gc_header(bucket)->color = vm->black;
|
gst_mark_value(vm, x.object->data[i + 1]);
|
||||||
gst_mark_value(vm, bucket->key);
|
|
||||||
gst_mark_value(vm, bucket->value);
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x.object->parent != NULL) {
|
if (x.object->parent != NULL) {
|
||||||
|
72
core/ids.c
72
core/ids.c
@ -205,32 +205,40 @@ void gst_cache_remove_struct(Gst *vm, char *structmem) {
|
|||||||
|
|
||||||
/* Begin creation of a struct */
|
/* Begin creation of a struct */
|
||||||
GstValue *gst_struct_begin(Gst *vm, uint32_t count) {
|
GstValue *gst_struct_begin(Gst *vm, uint32_t count) {
|
||||||
char *data = gst_alloc(vm, sizeof(uint32_t) * 2 + 4 * count * sizeof(GstValue));
|
char *data = gst_zalloc(vm, sizeof(uint32_t) * 2 + 4 * count * sizeof(GstValue));
|
||||||
GstValue *st = (GstValue *) (data + 2 * sizeof(uint32_t));
|
GstValue *st = (GstValue *) (data + 2 * sizeof(uint32_t));
|
||||||
gst_struct_length(st) = count;
|
gst_struct_length(st) = count;
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put a kv pair into a struct that has not yet been fully constructed. */
|
/* Find an item in a struct */
|
||||||
void gst_struct_put(GstValue *st, GstValue key, GstValue value) {
|
static const GstValue *gst_struct_find(const GstValue *st, GstValue key) {
|
||||||
uint32_t cap = gst_struct_capacity(st);
|
uint32_t cap = gst_struct_capacity(st);
|
||||||
uint32_t index = (gst_hash(key) % (cap / 2)) * 2;
|
uint32_t index = (gst_hash(key) % (cap / 2)) * 2;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = index; i < cap; i += 2) {
|
for (i = index; i < cap; i += 2) {
|
||||||
if (st[i + 1].type == GST_NIL) {
|
if (st[i].type == GST_NIL || gst_equals(st[i], key)) {
|
||||||
st[i] = key;
|
return st + i;
|
||||||
st[i + 1] = value;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < index; i += 2) {
|
for (i = 0; i < index; i += 2) {
|
||||||
if (st[i + 1].type == GST_NIL) {
|
if (st[i].type == GST_NIL || gst_equals(st[i], key)) {
|
||||||
st[i] = key;
|
return st + i;
|
||||||
st[i + 1] = value;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Should not get here if struct was initialized with proper size */
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put a kv pair into a struct that has not yet been fully constructed.
|
||||||
|
* Behavior is undefined if too many keys are added, or if a key is added
|
||||||
|
* twice. Nil keys and values are ignored. */
|
||||||
|
void gst_struct_put(GstValue *st, GstValue key, GstValue value) {
|
||||||
|
GstValue *bucket;
|
||||||
|
if (key.type == GST_NIL || value.type == GST_NIL) return;
|
||||||
|
bucket = (GstValue *) gst_struct_find(st, key);
|
||||||
|
if (!bucket) return;
|
||||||
|
bucket[0] = key;
|
||||||
|
bucket[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish building a struct */
|
/* Finish building a struct */
|
||||||
@ -246,27 +254,35 @@ const GstValue *gst_struct_end(Gst *vm, GstValue *st) {
|
|||||||
|
|
||||||
/* Get an item from a struct */
|
/* Get an item from a struct */
|
||||||
GstValue gst_struct_get(const GstValue *st, GstValue key) {
|
GstValue gst_struct_get(const GstValue *st, GstValue key) {
|
||||||
|
GstValue *bucket = gst_struct_find(st, key);
|
||||||
|
if (!bucket || bucket[0].type == GST_NIL) {
|
||||||
|
GstValue ret;
|
||||||
|
ret.type = GST_NIL;
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return bucket[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next key in a struct */
|
||||||
|
GstValue gst_struct_next(const GstValue *st, GstValue key) {
|
||||||
GstValue ret;
|
GstValue ret;
|
||||||
uint32_t cap = gst_struct_capacity(st);
|
const GstValue *bucket;
|
||||||
uint32_t index = (gst_hash(key) % (cap / 2)) * 2;
|
if (key.type == GST_NIL)
|
||||||
uint32_t i;
|
bucket = st - 2;
|
||||||
for (i = index; i < cap; i += 2) {
|
else
|
||||||
if (st[i + 1].type == GST_NIL) {
|
bucket = gst_struct_find(st, key);
|
||||||
goto notfound;
|
if (bucket && bucket[0].type != GST_NIL) {
|
||||||
} else if (gst_equals(st[i], key)) {
|
const GstValue *nextbucket, *end;
|
||||||
return st[i + 1];
|
end = st + gst_struct_capacity(st);
|
||||||
|
for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) {
|
||||||
|
if (nextbucket[0].type != GST_NIL)
|
||||||
|
return nextbucket[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < index; i += 2) {
|
|
||||||
if (st[i + 1].type == GST_NIL) {
|
|
||||||
goto notfound;
|
|
||||||
} else if (gst_equals(st[i], key)) {
|
|
||||||
return st[i + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notfound:
|
|
||||||
ret.type = GST_NIL;
|
ret.type = GST_NIL;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
17
core/stl.c
17
core/stl.c
@ -237,7 +237,7 @@ int gst_stl_object(Gst *vm) {
|
|||||||
if (count % 2 != 0) {
|
if (count % 2 != 0) {
|
||||||
gst_c_throwc(vm, "expected even number of arguments");
|
gst_c_throwc(vm, "expected even number of arguments");
|
||||||
}
|
}
|
||||||
object = gst_object(vm, count / 2);
|
object = gst_object(vm, count * 2);
|
||||||
for (i = 0; i < count; i += 2) {
|
for (i = 0; i < count; i += 2) {
|
||||||
gst_object_put(vm, object, gst_arg(vm, i), gst_arg(vm, i + 1));
|
gst_object_put(vm, object, gst_arg(vm, i), gst_arg(vm, i + 1));
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ int gst_stl_struct(Gst *vm) {
|
|||||||
if (count % 2 != 0) {
|
if (count % 2 != 0) {
|
||||||
gst_c_throwc(vm, "expected even number of arguments");
|
gst_c_throwc(vm, "expected even number of arguments");
|
||||||
}
|
}
|
||||||
st = gst_struct_begin(vm, count / 2);
|
st = gst_struct_begin(vm, count * 2);
|
||||||
for (i = 0; i < count; i += 2) {
|
for (i = 0; i < count; i += 2) {
|
||||||
gst_struct_put(st, gst_arg(vm, i), gst_arg(vm, i + 1));
|
gst_struct_put(st, gst_arg(vm, i), gst_arg(vm, i + 1));
|
||||||
}
|
}
|
||||||
@ -340,6 +340,19 @@ int gst_stl_rawset(Gst *vm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get next key in struct or object */
|
||||||
|
int gst_stl_next(Gst *vm) {
|
||||||
|
GstValue ds = gst_arg(vm, 0);
|
||||||
|
GstValue key = gst_arg(vm, 1);
|
||||||
|
if (ds.type == GST_OBJECT) {
|
||||||
|
gst_c_return(vm, gst_object_next(ds.data.object, key));
|
||||||
|
} else if (ds.type == GST_STRUCT) {
|
||||||
|
gst_c_return(vm, gst_struct_next(ds.data.st, key));
|
||||||
|
} else {
|
||||||
|
gst_c_throwc(vm, "expected object or struct");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Print values for inspection */
|
/* Print values for inspection */
|
||||||
int gst_stl_print(Gst *vm) {
|
int gst_stl_print(Gst *vm) {
|
||||||
uint32_t j, count;
|
uint32_t j, count;
|
||||||
|
@ -371,7 +371,7 @@ static int gst_continue_size(Gst *vm, uint32_t stackBase) {
|
|||||||
{
|
{
|
||||||
uint32_t i = 3;
|
uint32_t i = 3;
|
||||||
uint32_t kvs = pc[2];
|
uint32_t kvs = pc[2];
|
||||||
GstObject *o = gst_object(vm, kvs + 2);
|
GstObject *o = gst_object(vm, 2 * kvs + 2);
|
||||||
kvs = kvs + 3;
|
kvs = kvs + 3;
|
||||||
while (i < kvs) {
|
while (i < kvs) {
|
||||||
v1 = stack[pc[i++]];
|
v1 = stack[pc[i++]];
|
||||||
|
@ -134,9 +134,6 @@ typedef struct GstFuncDef GstFuncDef;
|
|||||||
typedef struct GstFuncEnv GstFuncEnv;
|
typedef struct GstFuncEnv GstFuncEnv;
|
||||||
typedef union GstValueUnion GstValueUnion;
|
typedef union GstValueUnion GstValueUnion;
|
||||||
|
|
||||||
/* Definitely implementation details */
|
|
||||||
typedef struct GstBucket GstBucket;
|
|
||||||
|
|
||||||
/* API Types */
|
/* API Types */
|
||||||
typedef struct GstModuleItem GstModuleItem;
|
typedef struct GstModuleItem GstModuleItem;
|
||||||
|
|
||||||
@ -208,7 +205,8 @@ struct GstBuffer {
|
|||||||
struct GstObject {
|
struct GstObject {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
GstBucket **buckets;
|
uint32_t deleted;
|
||||||
|
GstValue *data;
|
||||||
GstObject *parent;
|
GstObject *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -240,13 +238,6 @@ struct GstFunction {
|
|||||||
GstFunction *parent;
|
GstFunction *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A hash table bucket in an object */
|
|
||||||
struct GstBucket {
|
|
||||||
GstValue key;
|
|
||||||
GstValue value;
|
|
||||||
GstBucket *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Contains information about userdata */
|
/* Contains information about userdata */
|
||||||
struct GstUserdataHeader {
|
struct GstUserdataHeader {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
@ -381,6 +372,7 @@ GstValue *gst_struct_begin(Gst *vm, uint32_t count);
|
|||||||
void gst_struct_put(GstValue *st, GstValue key, GstValue value);
|
void gst_struct_put(GstValue *st, GstValue key, GstValue value);
|
||||||
const GstValue *gst_struct_end(Gst *vm, GstValue *st);
|
const GstValue *gst_struct_end(Gst *vm, GstValue *st);
|
||||||
GstValue gst_struct_get(const GstValue *st, GstValue key);
|
GstValue gst_struct_get(const GstValue *st, GstValue key);
|
||||||
|
GstValue gst_struct_next(const GstValue *st, GstValue key);
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* Object functions */
|
/* Object functions */
|
||||||
@ -388,8 +380,9 @@ GstValue gst_struct_get(const GstValue *st, GstValue key);
|
|||||||
|
|
||||||
GstObject *gst_object(Gst *vm, uint32_t capacity);
|
GstObject *gst_object(Gst *vm, uint32_t capacity);
|
||||||
GstValue gst_object_get(GstObject *obj, GstValue key);
|
GstValue gst_object_get(GstObject *obj, GstValue key);
|
||||||
GstValue gst_object_remove(Gst *vm, GstObject *obj, GstValue key);
|
GstValue gst_object_remove(GstObject *obj, GstValue key);
|
||||||
void gst_object_put(Gst *vm, GstObject *obj, GstValue key, GstValue value);
|
void gst_object_put(Gst *vm, GstObject *obj, GstValue key, GstValue value);
|
||||||
|
GstValue gst_object_next(GstObject *o, GstValue key);
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* Threads */
|
/* Threads */
|
||||||
|
Loading…
Reference in New Issue
Block a user