summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/array.c6
-rw-r--r--src/class.c22
-rw-r--r--src/codedump.c14
-rw-r--r--src/error.c7
-rw-r--r--src/etc.c3
-rw-r--r--src/fmt_fp.c4
-rw-r--r--src/gc.c5
-rw-r--r--src/hash.c7
-rw-r--r--src/kernel.c44
-rw-r--r--src/numeric.c12
-rw-r--r--src/proc.c75
-rw-r--r--src/state.c4
-rw-r--r--src/string.c12
-rw-r--r--src/symbol.c2
-rw-r--r--src/variable.c12
-rw-r--r--src/vm.c342
16 files changed, 179 insertions, 392 deletions
diff --git a/src/array.c b/src/array.c
index 707820ab9..d4302cb22 100644
--- a/src/array.c
+++ b/src/array.c
@@ -120,9 +120,7 @@ ary_fill_with_nil(mrb_value *ptr, mrb_int size)
static void
ary_modify_check(mrb_state *mrb, struct RArray *a)
{
- if (MRB_FROZEN_P(a)) {
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen array");
- }
+ mrb_check_frozen(mrb, a);
}
static void
@@ -1286,7 +1284,6 @@ mrb_init_array(mrb_state *mrb)
mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */
mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */
mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */
- mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY());
mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */
mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
@@ -1295,7 +1292,6 @@ mrb_init_array(mrb_state *mrb)
mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */
mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */
mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */
- mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY());
mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1));
mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1));
diff --git a/src/class.c b/src/class.c
index 5c5ee9d17..d6efdbdc4 100644
--- a/src/class.c
+++ b/src/class.c
@@ -441,12 +441,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
MRB_CLASS_ORIGIN(c);
h = c->mt;
- if (MRB_FROZEN_P(c)) {
- if (c->tt == MRB_TT_MODULE)
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen module");
- else
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen class");
- }
+ mrb_check_frozen(mrb, c);
if (!h) h = c->mt = kh_init(mt, mrb);
k = kh_put(mt, mrb, h, mid);
kh_value(h, k) = m;
@@ -1503,29 +1498,20 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
*
*/
-MRB_API mrb_value
+mrb_value
mrb_instance_new(mrb_state *mrb, mrb_value cv)
{
mrb_value obj, blk;
mrb_value *argv;
mrb_int argc;
mrb_sym init;
- mrb_method_t m;
mrb_get_args(mrb, "*&", &argv, &argc, &blk);
obj = mrb_instance_alloc(mrb, cv);
init = mrb_intern_lit(mrb, "initialize");
- m = mrb_method_search(mrb, mrb_class(mrb, obj), init);
- if (MRB_METHOD_CFUNC_P(m)) {
- mrb_func_t f = MRB_METHOD_CFUNC(m);
- if (f != mrb_bob_init) {
- f(mrb, obj);
- }
- }
- else {
+ if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) {
mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
}
-
return obj;
}
@@ -1843,7 +1829,7 @@ mrb_mod_alias(mrb_state *mrb, mrb_value mod)
mrb_get_args(mrb, "nn", &new_name, &old_name);
mrb_alias_method(mrb, c, new_name, old_name);
- return mrb_nil_value();
+ return mod;
}
void
diff --git a/src/codedump.c b/src/codedump.c
index 5bffefddb..12d609075 100644
--- a/src/codedump.c
+++ b/src/codedump.c
@@ -266,13 +266,13 @@ codedump(mrb_state *mrb, mrb_irep *irep)
break;
CASE(OP_ENTER, W):
printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
- (a>>18)&0x1f,
- (a>>13)&0x1f,
- (a>>12)&0x1,
- (a>>7)&0x1f,
- (a>>2)&0x1f,
- (a>>1)&0x1,
- a & 0x1);
+ MRB_ASPEC_REQ(a),
+ MRB_ASPEC_OPT(a),
+ MRB_ASPEC_REST(a),
+ MRB_ASPEC_POST(a),
+ MRB_ASPEC_KEY(a),
+ MRB_ASPEC_KDICT(a),
+ MRB_ASPEC_BLOCK(a));
break;
CASE(OP_KEY_P, BB):
printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b]));
diff --git a/src/error.c b/src/error.c
index e69812dda..4c1b67c99 100644
--- a/src/error.c
+++ b/src/error.c
@@ -484,6 +484,13 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt,
mrb_exc_raise(mrb, exc);
}
+MRB_API mrb_noreturn void
+mrb_frozen_error(mrb_state *mrb, void *frozen_obj)
+{
+ mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S",
+ mrb_obj_value(mrb_class(mrb, mrb_obj_value(frozen_obj))));
+}
+
void
mrb_init_exception(mrb_state *mrb)
{
diff --git a/src/etc.c b/src/etc.c
index 12d948a55..d15b398dd 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -167,6 +167,7 @@ mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
v.value.fp->f = f;
+ MRB_SET_FROZEN_FLAG(v.value.bp);
return v;
}
@@ -177,6 +178,7 @@ mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
nf->tt = MRB_TT_FLOAT;
nf->c = mrb->float_class;
nf->f = f;
+ MRB_SET_FROZEN_FLAG(nf);
return mrb_obj_value(nf);
}
#endif /* MRB_WITHOUT_FLOAT */
@@ -203,7 +205,6 @@ mrb_regexp_p(mrb_state *mrb, mrb_value v)
return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
}
else {
- mrb->flags |= MRB_STATE_REGEXP;
mrb->flags |= MRB_STATE_NO_REGEXP;
}
return FALSE;
diff --git a/src/fmt_fp.c b/src/fmt_fp.c
index 14c74ef9e..1f1af6764 100644
--- a/src/fmt_fp.c
+++ b/src/fmt_fp.c
@@ -372,7 +372,7 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
}
return f.str;
}
-#else /* MRB_DISABLE_STDIO */
+#else /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
#include <mruby.h>
#include <stdio.h>
@@ -384,5 +384,5 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
snprintf(buf, sizeof(buf), fmt, mrb_float(flo));
return mrb_str_new_cstr(mrb, buf);
}
-#endif /* MRB_DISABLE_STDIO */
+#endif /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
#endif
diff --git a/src/gc.c b/src/gc.c
index ec52787e8..27f3716ec 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -10,6 +10,7 @@
#include <mruby/array.h>
#include <mruby/class.h>
#include <mruby/data.h>
+#include <mruby/istruct.h>
#include <mruby/hash.h>
#include <mruby/proc.h>
#include <mruby/range.h>
@@ -109,8 +110,10 @@ typedef struct {
struct RHash hash;
struct RRange range;
struct RData data;
+ struct RIstruct istruct;
struct RProc proc;
struct REnv env;
+ struct RFiber fiber;
struct RException exc;
struct RBreak brk;
#ifdef MRB_WORD_BOXING
@@ -396,7 +399,7 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc)
static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
-void
+static void
free_heap(mrb_state *mrb, mrb_gc *gc)
{
mrb_heap_page *page = gc->heaps;
diff --git a/src/hash.c b/src/hash.c
index fd963c3de..a9367a426 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -182,7 +182,7 @@ ht_index(mrb_state *mrb, htable *t)
if (!index || index->capa < size) {
index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size);
if (index == NULL) {
- mrb_free(mrb, index);
+ mrb_free(mrb, t->index);
t->index = NULL;
return;
}
@@ -746,10 +746,7 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
static void
mrb_hash_modify(mrb_state *mrb, mrb_value hash)
{
- if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen hash");
- }
-
+ mrb_check_frozen(mrb, mrb_hash_ptr(hash));
if (!RHASH_TBL(hash)) {
RHASH_TBL(hash) = ht_new(mrb);
}
diff --git a/src/kernel.c b/src/kernel.c
index 7890e3dac..d9a1d36ce 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -434,24 +434,11 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_obj_freeze(mrb_state *mrb, mrb_value self)
{
- struct RBasic *b;
-
- switch (mrb_type(self)) {
- case MRB_TT_FALSE:
- case MRB_TT_TRUE:
- case MRB_TT_FIXNUM:
- case MRB_TT_SYMBOL:
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
-#endif
- return self;
- default:
- break;
- }
-
- b = mrb_basic_ptr(self);
- if (!MRB_FROZEN_P(b)) {
- MRB_SET_FROZEN_FLAG(b);
+ if (!mrb_immediate_p(self)) {
+ struct RBasic *b = mrb_basic_ptr(self);
+ if (!MRB_FROZEN_P(b)) {
+ MRB_SET_FROZEN_FLAG(b);
+ }
}
return self;
}
@@ -459,26 +446,7 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_obj_frozen(mrb_state *mrb, mrb_value self)
{
- struct RBasic *b;
-
- switch (mrb_type(self)) {
- case MRB_TT_FALSE:
- case MRB_TT_TRUE:
- case MRB_TT_FIXNUM:
- case MRB_TT_SYMBOL:
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
-#endif
- return mrb_true_value();
- default:
- break;
- }
-
- b = mrb_basic_ptr(self);
- if (!MRB_FROZEN_P(b)) {
- return mrb_false_value();
- }
- return mrb_true_value();
+ return mrb_bool_value(mrb_immediate_p(self) || MRB_FROZEN_P(mrb_basic_ptr(self)));
}
/* 15.3.1.3.15 */
diff --git a/src/numeric.c b/src/numeric.c
index 4128ea3a6..8205e41f6 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -207,12 +207,12 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g";
mrb_value str = mrb_float_to_str(mrb, flt, fmt);
mrb_int len;
- char *begp;
+ char *begp, *p, *endp;
insert_dot_zero:
begp = RSTRING_PTR(str);
len = RSTRING_LEN(str);
- for (char *p = begp, *endp = p + len; p < endp; ++p) {
+ for (p = begp, endp = p + len; p < endp; ++p) {
if (*p == '.') {
return str;
}
@@ -510,7 +510,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
}
static mrb_value
-flo_lshift(mrb_state *mrb, mrb_value x)
+flo_rshift(mrb_state *mrb, mrb_value x)
{
mrb_int width;
@@ -519,7 +519,7 @@ flo_lshift(mrb_state *mrb, mrb_value x)
}
static mrb_value
-flo_rshift(mrb_state *mrb, mrb_value x)
+flo_lshift(mrb_state *mrb, mrb_value x)
{
mrb_int width;
@@ -1608,8 +1608,8 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1));
mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1));
mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, fl, ">>", flo_lshift, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, fl, "<<", flo_rshift, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1));
mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */
mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */
mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */
diff --git a/src/proc.c b/src/proc.c
index dab95e465..094fff816 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -213,46 +213,11 @@ mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
return self;
}
-int
-mrb_proc_cfunc_p(struct RProc *p)
-{
- return MRB_PROC_CFUNC_P(p);
-}
-
/* 15.2.17.4.2 */
static mrb_value
-mrb_proc_arity(mrb_state *mrb, mrb_value self)
+proc_arity(mrb_state *mrb, mrb_value self)
{
- struct RProc *p = mrb_proc_ptr(self);
- struct mrb_irep *irep;
- mrb_code *pc;
- mrb_aspec aspec;
- int ma, op, ra, pa, arity;
-
- if (MRB_PROC_CFUNC_P(p)) {
- /* TODO cfunc aspec not implemented yet */
- return mrb_fixnum_value(-1);
- }
-
- irep = p->body.irep;
- if (!irep) {
- return mrb_fixnum_value(0);
- }
-
- pc = irep->iseq;
- /* arity is depend on OP_ENTER */
- if (*pc != OP_ENTER) {
- return mrb_fixnum_value(0);
- }
-
- aspec = PEEK_W(pc+1);
- ma = MRB_ASPEC_REQ(aspec);
- op = MRB_ASPEC_OPT(aspec);
- ra = MRB_ASPEC_REST(aspec);
- pa = MRB_ASPEC_POST(aspec);
- arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
-
- return mrb_fixnum_value(arity);
+ return mrb_fixnum_value(mrb_proc_arity(mrb_proc_ptr(self)));
}
/* 15.3.1.2.6 */
@@ -287,6 +252,40 @@ proc_lambda(mrb_state *mrb, mrb_value self)
return blk;
}
+mrb_int
+mrb_proc_arity(const struct RProc *p)
+{
+ struct mrb_irep *irep;
+ mrb_code *pc;
+ mrb_aspec aspec;
+ int ma, op, ra, pa, arity;
+
+ if (MRB_PROC_CFUNC_P(p)) {
+ /* TODO cfunc aspec not implemented yet */
+ return -1;
+ }
+
+ irep = p->body.irep;
+ if (!irep) {
+ return 0;
+ }
+
+ pc = irep->iseq;
+ /* arity is depend on OP_ENTER */
+ if (*pc != OP_ENTER) {
+ return 0;
+ }
+
+ aspec = PEEK_W(pc+1);
+ ma = MRB_ASPEC_REQ(aspec);
+ op = MRB_ASPEC_OPT(aspec);
+ ra = MRB_ASPEC_REST(aspec);
+ pa = MRB_ASPEC_POST(aspec);
+ arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
+
+ return arity;
+}
+
void
mrb_init_proc(mrb_state *mrb)
{
@@ -303,7 +302,7 @@ mrb_init_proc(mrb_state *mrb)
mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
+ mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE());
p = mrb_proc_new(mrb, call_irep);
MRB_METHOD_FROM_PROC(m, p);
diff --git a/src/state.c b/src/state.c
index c3ce1dc33..08d7ba906 100644
--- a/src/state.c
+++ b/src/state.c
@@ -42,10 +42,6 @@ mrb_open_core(mrb_allocf f, void *ud)
mrb_init_core(mrb);
-#if !defined(MRB_DISABLE_STDIO) && defined(_MSC_VER) && _MSC_VER < 1900
- _set_output_format(_TWO_DIGIT_EXPONENT);
-#endif
-
return mrb;
}
diff --git a/src/string.c b/src/string.c
index 63c592d59..f7a805a94 100644
--- a/src/string.c
+++ b/src/string.c
@@ -493,20 +493,12 @@ str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset)
return mrb_str_index(mrb, str, ptr, len, offset);
}
-static void
-check_frozen(mrb_state *mrb, struct RString *s)
-{
- if (MRB_FROZEN_P(s)) {
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen string");
- }
-}
-
static mrb_value
str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
{
mrb_int len;
- check_frozen(mrb, s1);
+ mrb_check_frozen(mrb, s1);
if (s1 == s2) return mrb_obj_value(s1);
s1->flags &= ~MRB_STR_NO_UTF;
s1->flags |= s2->flags&MRB_STR_NO_UTF;
@@ -646,7 +638,7 @@ mrb_locale_from_utf8(const char *utf8, int len)
MRB_API void
mrb_str_modify(mrb_state *mrb, struct RString *s)
{
- check_frozen(mrb, s);
+ mrb_check_frozen(mrb, s);
s->flags &= ~MRB_STR_NO_UTF;
if (RSTR_SHARED_P(s)) {
mrb_shared_string *shared = s->as.heap.aux.shared;
diff --git a/src/symbol.c b/src/symbol.c
index 96ca9dd17..b26f2b1fd 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -91,7 +91,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp)
}
#endif
-uint8_t
+static uint8_t
symhash(const char *key, size_t len)
{
uint32_t hash, i;
diff --git a/src/variable.c b/src/variable.c
index 9edfb32bd..983fe52f7 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -79,19 +79,19 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
}
/* Not found */
- t->size++;
if (matched_seg) {
matched_seg->key[matched_idx] = sym;
matched_seg->val[matched_idx] = val;
+ t->size++;
return;
}
seg = (segment*)mrb_malloc(mrb, sizeof(segment));
- if (!seg) return;
seg->next = NULL;
seg->key[0] = sym;
seg->val[0] = val;
t->last_len = 1;
+ t->size++;
if (prev) {
prev->next = seg;
}
@@ -346,9 +346,7 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
{
iv_tbl *t;
- if (MRB_FROZEN_P(obj)) {
- mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
- }
+ mrb_check_frozen(mrb, obj);
assign_class_name(mrb, obj, sym, v);
if (!obj->iv) {
obj->iv = iv_new(mrb);
@@ -1116,7 +1114,9 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
mrb_bool
mrb_ident_p(const char *s, mrb_int len)
{
- for (mrb_int i = 0; i < len; i++) {
+ mrb_int i;
+
+ for (i = 0; i < len; i++) {
if (!identchar(s[i])) return FALSE;
}
return TRUE;
diff --git a/src/vm.c b/src/vm.c
index a381de21f..9c07b8caa 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -486,6 +486,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
ci->argc = (int)argc;
ci->target_class = c;
mrb->c->stack = mrb->c->stack + n;
+ if (argc < 0) argc = 1;
if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
voff = argv - mrb->c->stbase;
}
@@ -500,11 +501,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
ci->argc = -1;
argc = 1;
}
- else {
+ else if (MRB_METHOD_PROC_P(m)) {
struct RProc *p = MRB_METHOD_PROC(m);
ci->proc = p;
- if (argc < 0) argc = 1;
mrb_stack_extend(mrb, p->body.irep->nregs + argc);
}
if (voff >= 0) {
@@ -520,9 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
int ai = mrb_gc_arena_save(mrb);
ci->acc = CI_ACC_DIRECT;
- if (MRB_METHOD_PROC_P(m)) {
- ci->proc = MRB_METHOD_PROC(m);
- }
val = MRB_METHOD_CFUNC(m)(mrb, self);
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb);
@@ -1004,7 +1001,7 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
MRB_API mrb_value
mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
{
- /* mrb_assert(mrb_proc_cfunc_p(proc)) */
+ /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
mrb_code *pc0 = pc;
mrb_irep *irep = proc->body.irep;
mrb_value *pool = irep->pool;
@@ -2217,184 +2214,67 @@ RETRY_TRY_BLOCK:
}
#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
-#define OP_MATH_BODY(op,v1,v2) do {\
- v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\
-} while(0)
-
- CASE(OP_ADD, B) {
- /* need to check if op is overridden */
- switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
- {
- mrb_int x, y, z;
- mrb_value *regs_a = regs + a;
-
- x = mrb_fixnum(regs_a[0]);
- y = mrb_fixnum(regs_a[1]);
- if (mrb_int_add_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
- SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
- break;
-#endif
- }
- SET_INT_VALUE(regs[a], z);
- }
- break;
-#ifndef MRB_WITHOUT_FLOAT
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
- }
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x + y);
- }
-#else
- OP_MATH_BODY(+,mrb_float,mrb_fixnum);
-#endif
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x + y);
- }
+#define OP_MATH(op_name) \
+ /* need to check if op is overridden */ \
+ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \
+ OP_MATH_CASE_FIXNUM(op_name); \
+ OP_MATH_CASE_FLOAT(op_name, fixnum, float); \
+ OP_MATH_CASE_FLOAT(op_name, float, fixnum); \
+ OP_MATH_CASE_FLOAT(op_name, float, float); \
+ OP_MATH_CASE_STRING_##op_name(); \
+ default: \
+ c = 1; \
+ mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \
+ goto L_SEND_SYM; \
+ } \
+ NEXT;
+#define OP_MATH_CASE_FIXNUM(op_name) \
+ case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \
+ { \
+ mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \
+ if (mrb_int_##op_name##_overflow(x, y, &z)) \
+ OP_MATH_OVERFLOW_INT(op_name, x, y, z); \
+ else \
+ SET_INT_VALUE(regs[a], z); \
+ } \
+ break
+#ifdef MRB_WITHOUT_FLOAT
+#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
+#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z)
#else
- OP_MATH_BODY(+,mrb_float,mrb_float);
+#define OP_MATH_CASE_FLOAT(op_name, t1, t2) \
+ case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \
+ { \
+ mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \
+ SET_FLOAT_VALUE(mrb, regs[a], z); \
+ } \
+ break
+#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \
+ SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y)
#endif
- break;
-#endif
- case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
- regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
- break;
- default:
- c = 1;
- mid = mrb_intern_lit(mrb, "+");
- goto L_SEND_SYM;
- }
- mrb_gc_arena_restore(mrb, ai);
- NEXT;
+#define OP_MATH_CASE_STRING_add() \
+ case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \
+ regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \
+ mrb_gc_arena_restore(mrb, ai); \
+ break
+#define OP_MATH_CASE_STRING_sub() (void)0
+#define OP_MATH_CASE_STRING_mul() (void)0
+#define OP_MATH_OP_add +
+#define OP_MATH_OP_sub -
+#define OP_MATH_OP_mul *
+#define OP_MATH_TT_fixnum MRB_TT_FIXNUM
+#define OP_MATH_TT_float MRB_TT_FLOAT
+
+ CASE(OP_ADD, B) {
+ OP_MATH(add);
}
CASE(OP_SUB, B) {
- /* need to check if op is overridden */
- switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
- {
- mrb_int x, y, z;
-
- x = mrb_fixnum(regs[a]);
- y = mrb_fixnum(regs[a+1]);
- if (mrb_int_sub_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
- break;
-#endif
- }
- SET_INT_VALUE(regs[a], z);
- }
- break;
-#ifndef MRB_WITHOUT_FLOAT
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
- }
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x - y);
- }
-#else
- OP_MATH_BODY(-,mrb_float,mrb_fixnum);
-#endif
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x - y);
- }
-#else
- OP_MATH_BODY(-,mrb_float,mrb_float);
-#endif
- break;
-#endif
- default:
- c = 1;
- mid = mrb_intern_lit(mrb, "-");
- goto L_SEND_SYM;
- }
- NEXT;
+ OP_MATH(sub);
}
CASE(OP_MUL, B) {
- /* need to check if op is overridden */
- switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
- {
- mrb_int x, y, z;
-
- x = mrb_fixnum(regs[a]);
- y = mrb_fixnum(regs[a+1]);
- if (mrb_int_mul_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
- break;
-#endif
- }
- SET_INT_VALUE(regs[a], z);
- }
- break;
-#ifndef MRB_WITHOUT_FLOAT
- case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
- }
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x * y);
- }
-#else
- OP_MATH_BODY(*,mrb_float,mrb_fixnum);
-#endif
- break;
- case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x * y);
- }
-#else
- OP_MATH_BODY(*,mrb_float,mrb_float);
-#endif
- break;
-#endif
- default:
- c = 1;
- mid = mrb_intern_lit(mrb, "*");
- goto L_SEND_SYM;
- }
- NEXT;
+ OP_MATH(mul);
}
CASE(OP_DIV, B) {
@@ -2449,84 +2329,46 @@ RETRY_TRY_BLOCK:
NEXT;
}
- CASE(OP_ADDI, BB) {
- /* need to check if + is overridden */
- switch (mrb_type(regs[a])) {
- case MRB_TT_FIXNUM:
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_int y = (mrb_int)b;
- mrb_int z;
-
- if (mrb_int_add_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
- break;
-#endif
- }
- SET_INT_VALUE(regs[a], z);
- }
- break;
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- SET_FLOAT_VALUE(mrb, regs[a], x + b);
- }
+#define OP_MATHI(op_name) \
+ /* need to check if op is overridden */ \
+ switch (mrb_type(regs[a])) { \
+ OP_MATHI_CASE_FIXNUM(op_name); \
+ OP_MATHI_CASE_FLOAT(op_name); \
+ default: \
+ SET_INT_VALUE(regs[a+1], b); \
+ c = 1; \
+ mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \
+ goto L_SEND_SYM; \
+ } \
+ NEXT;
+#define OP_MATHI_CASE_FIXNUM(op_name) \
+ case MRB_TT_FIXNUM: \
+ { \
+ mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \
+ if (mrb_int_##op_name##_overflow(x, y, &z)) \
+ OP_MATH_OVERFLOW_INT(op_name, x, y, z); \
+ else \
+ SET_INT_VALUE(regs[a], z); \
+ } \
+ break
+#ifdef MRB_WITHOUT_FLOAT
+#define OP_MATHI_CASE_FLOAT(op_name) (void)0
#else
- mrb_float(regs[a]) += b;
-#endif
- break;
+#define OP_MATHI_CASE_FLOAT(op_name) \
+ case MRB_TT_FLOAT: \
+ { \
+ mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \
+ SET_FLOAT_VALUE(mrb, regs[a], z); \
+ } \
+ break
#endif
- default:
- SET_INT_VALUE(regs[a+1], b);
- c = 1;
- mid = mrb_intern_lit(mrb, "+");
- goto L_SEND_SYM;
- }
- NEXT;
+
+ CASE(OP_ADDI, BB) {
+ OP_MATHI(add);
}
CASE(OP_SUBI, BB) {
- mrb_value *regs_a = regs + a;
-
- /* need to check if + is overridden */
- switch (mrb_type(regs_a[0])) {
- case MRB_TT_FIXNUM:
- {
- mrb_int x = mrb_fixnum(regs_a[0]);
- mrb_int y = (mrb_int)b;
- mrb_int z;
-
- if (mrb_int_sub_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
- SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
- break;
-#endif
- }
- SET_INT_VALUE(regs_a[0], z);
- }
- break;
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b);
- }
-#else
- mrb_float(regs_a[0]) -= b;
-#endif
- break;
-#endif
- default:
- SET_INT_VALUE(regs_a[1], b);
- c = 1;
- mid = mrb_intern_lit(mrb, "-");
- goto L_SEND_SYM;
- }
- NEXT;
+ OP_MATHI(sub);
}
#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
@@ -3021,11 +2863,11 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
return mrb_vm_run(mrb, proc, self, stack_keep);
}
ci = cipush(mrb);
+ ci->stackent = mrb->c->stack;
ci->mid = 0;
ci->acc = CI_ACC_SKIP;
ci->target_class = mrb->object_class;
v = mrb_vm_run(mrb, proc, self, stack_keep);
- cipop(mrb);
return v;
}