summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hash.c30
-rw-r--r--src/variable.c29
-rw-r--r--src/vm.c5
3 files changed, 36 insertions, 28 deletions
diff --git a/src/hash.c b/src/hash.c
index 467b20a51..3d6c2ed7d 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -16,13 +16,10 @@
mrb_int mrb_float_id(mrb_float f);
#endif
-/* return non zero to break the loop */
-typedef int (ht_foreach_func)(mrb_state *mrb,mrb_value key, mrb_value val, void *data);
-
#ifndef MRB_HT_INIT_SIZE
#define MRB_HT_INIT_SIZE 4
#endif
-#define HT_SEG_INCREASE_RATIO 1.2
+#define HT_SEG_INCREASE_RATIO 6 / 5
struct segkv {
mrb_value key;
@@ -41,7 +38,7 @@ typedef struct segindex {
struct segkv *table[];
} segindex;
-/* Instance variable table structure */
+/* hash table structure */
typedef struct htable {
segment *rootseg;
segment *lastseg;
@@ -135,7 +132,7 @@ ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b)
}
}
-/* Creates the instance variable table. */
+/* Creates the hash table. */
static htable*
ht_new(mrb_state *mrb)
{
@@ -349,7 +346,7 @@ ht_index_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
t->size++;
}
-/* Set the value for the key in the table. */
+/* Set the value for the key in the hash table. */
static void
ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
{
@@ -468,7 +465,7 @@ ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
return FALSE;
}
-/* Deletes the value for the symbol from the instance variable table. */
+/* Deletes the value for the symbol from the hash table. */
/* Deletion is done by overwriting keys by `undef`. */
static mrb_bool
ht_del(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
@@ -499,9 +496,9 @@ ht_del(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
return FALSE;
}
-/* Iterates over the instance variable table. */
+/* Iterates over the hash table. */
static void
-ht_foreach(mrb_state *mrb, htable *t, ht_foreach_func *func, void *p)
+ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p)
{
segment *seg;
mrb_int i;
@@ -522,7 +519,14 @@ ht_foreach(mrb_state *mrb, htable *t, ht_foreach_func *func, void *p)
}
}
-/* Copy the instance variable table. */
+/* Iterates over the hash table. */
+MRB_API void
+mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p)
+{
+ ht_foreach(mrb, hash->ht, func, p);
+}
+
+/* Copy the hash table. */
static htable*
ht_copy(mrb_state *mrb, htable *t)
{
@@ -548,7 +552,7 @@ ht_copy(mrb_state *mrb, htable *t)
return t2;
}
-/* Free memory of the instance variable table. */
+/* Free memory of the hash table. */
static void
ht_free(mrb_state *mrb, htable *t)
{
@@ -1008,7 +1012,7 @@ mrb_hash_delete(mrb_state *mrb, mrb_value self)
return mrb_hash_delete_key(mrb, self, key);
}
-/* find first element in a hash table, and remove it. */
+/* find first element in the hash table, and remove it. */
static void
ht_shift(mrb_state *mrb, htable *t, mrb_value *kp, mrb_value *vp)
{
diff --git a/src/variable.c b/src/variable.c
index 72c13aa1f..14e9da9ef 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -9,8 +9,7 @@
#include <mruby/class.h>
#include <mruby/proc.h>
#include <mruby/string.h>
-
-typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
+#include <mruby/variable.h>
#ifndef MRB_IV_SEGMENT_SIZE
#define MRB_IV_SEGMENT_SIZE 4
@@ -156,14 +155,13 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
}
/* Iterates over the instance variable table. */
-static mrb_bool
-iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
+static void
+iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p)
{
segment *seg;
size_t i;
- int n;
- if (t == NULL) return TRUE;
+ if (t == NULL) return;
seg = t->rootseg;
while (seg) {
for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
@@ -171,20 +169,17 @@ iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
/* no value in last segment after last_len */
if (!seg->next && i >= t->last_len) {
- return FALSE;
+ return;
}
if (key != 0) {
- n =(*func)(mrb, key, seg->val[i], p);
- if (n > 0) return FALSE;
- if (n < 0) {
- t->size--;
- seg->key[i] = 0;
+ if ((*func)(mrb, key, seg->val[i], p) != 0) {
+ return;
}
}
}
seg = seg->next;
}
- return TRUE;
+ return;
}
/* Get the size of the instance variable table. */
@@ -363,6 +358,14 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
mrb_write_barrier(mrb, (struct RBasic*)obj);
}
+/* Iterates over the instance variable table. */
+MRB_API void
+mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
+{
+ if (!obj_iv_p(obj)) return;
+ iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p);
+}
+
static inline mrb_bool
namespace_p(enum mrb_vtype tt)
{
diff --git a/src/vm.c b/src/vm.c
index 84e076ee8..b5249b325 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -667,10 +667,11 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
return MRB_PROC_CFUNC(p)(mrb, self);
}
nregs = p->body.irep->nregs;
- mrb_stack_extend(mrb, (nregs < 3) ? 3 : nregs);
+ if (nregs < 3) nregs = 3;
+ mrb_stack_extend(mrb, nregs);
mrb->c->stack[0] = self;
mrb->c->stack[1] = self;
- mrb->c->stack[2] = mrb_nil_value();
+ stack_clear(mrb->c->stack+2, nregs-2);
ci = cipush(mrb);
ci->target_class = 0;
ci->pc = p->body.irep->iseq;