diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class.c | 16 | ||||
| -rw-r--r-- | src/error.c | 8 | ||||
| -rw-r--r-- | src/gc.c | 2 | ||||
| -rw-r--r-- | src/kernel.c | 25 | ||||
| -rw-r--r-- | src/proc.c | 63 | ||||
| -rw-r--r-- | src/re.c | 2 | ||||
| -rw-r--r-- | src/string.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 6 |
8 files changed, 91 insertions, 33 deletions
diff --git a/src/class.c b/src/class.c index 434ecb037..72fef70aa 100644 --- a/src/class.c +++ b/src/class.c @@ -1206,6 +1206,21 @@ mrb_mod_undef(mrb_state *mrb, mrb_value mod) return mrb_nil_value(); } +static mrb_value +mod_define_method(mrb_state *mrb, mrb_value self) +{ + struct RClass *c = mrb_class_ptr(self); + mrb_sym mid; + mrb_value blk; + + mrb_get_args(mrb, "n&", &mid, &blk); + if (mrb_nil_p(blk)) { + /* raise */ + } + mrb_define_method_raw(mrb, c, mid, mrb_proc_ptr(blk)); + return blk; +} + static mrb_sym mrb_sym_value(mrb_state *mrb, mrb_value val) { @@ -1310,6 +1325,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */ mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */ mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */ + mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1)); mrb_define_method(mrb, mod, "===", mrb_mod_eqq, ARGS_REQ(1)); } diff --git a/src/error.c b/src/error.c index b2d9a8c8d..1183d8643 100644 --- a/src/error.c +++ b/src/error.c @@ -301,7 +301,7 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr) if (isstr) { mesg = mrb_check_string_type(mrb, argv[0]); if (!mrb_nil_p(mesg)) { - mesg = mrb_exc_new3(mrb, mrb->eRuntimeError_class, mesg); + mesg = mrb_exc_new3(mrb, E_RUNTIME_ERROR, mesg); break; } } @@ -352,7 +352,7 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv) void mrb_sys_fail(mrb_state *mrb, const char *mesg) { - mrb_raise(mrb, mrb->eRuntimeError_class, "%s", mesg); + mrb_raise(mrb, E_RUNTIME_ERROR, "%s", mesg); } void @@ -369,6 +369,6 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, e, "message", exc_message, ARGS_NONE()); mrb_define_method(mrb, e, "inspect", exc_inspect, ARGS_NONE()); - mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ - mrb->eRuntimeError_class = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ + mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ + mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ } @@ -277,7 +277,7 @@ gc_protect(mrb_state *mrb, struct RBasic *p) if (mrb->arena_idx > MRB_ARENA_SIZE) { /* arena overflow error */ mrb->arena_idx = MRB_ARENA_SIZE - 4; /* force room in arena */ - mrb_raise(mrb, mrb->eRuntimeError_class, "arena overflow error"); + mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error"); } mrb->arena[mrb->arena_idx++] = p; } diff --git a/src/kernel.c b/src/kernel.c index 75c588a81..a9f4792d7 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -570,7 +570,7 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) mrb_value a, b; if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { - mrb_raise(mrb, mrb->eRuntimeError_class, "instance_eval with string not implemented"); + mrb_raise(mrb, E_RUNTIME_ERROR, "instance_eval with string not implemented"); } return mrb_yield_with_self(mrb, b, 0, 0, self); } @@ -791,22 +791,6 @@ mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) } } -/* 15.3.1.2.6 */ -/* 15.3.1.3.27 */ -/* - * call-seq: - * lambda { |...| block } -> a_proc - * - * Equivalent to <code>Proc.new</code>, except the resulting Proc objects - * check the number of parameters passed when called. - */ -mrb_value -proc_lambda(mrb_state *mrb, mrb_value self) -{ - //return mrb_block_lambda(); - return mrb_nil_value(); /* dummy */ -} - static void method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary) { @@ -1032,13 +1016,13 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); switch (argc) { case 0: - mrb_raise(mrb, mrb->eRuntimeError_class, ""); + mrb_raise(mrb, E_RUNTIME_ERROR, ""); break; case 1: a[1] = mrb_check_string_type(mrb, a[0]); if (!mrb_nil_p(a[1])) { argc = 2; - a[0] = mrb_obj_value(mrb->eRuntimeError_class); + a[0] = mrb_obj_value(E_RUNTIME_ERROR); } /* fall through */ default: @@ -1202,7 +1186,6 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.2 */ mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, ARGS_NONE()); /* 15.3.1.2.4 */ mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.5 */ - mrb_define_class_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */ ; /* 15.3.1.2.11 */ mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, ARGS_ANY()); /* 15.3.1.2.12 */ @@ -1233,7 +1216,6 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.24 */ mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.3.25 */ mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.26 */ - mrb_define_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */ mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, ARGS_ANY()); /* 15.3.1.3.31 */ mrb_define_method(mrb, krn, "nil?", mrb_false, ARGS_NONE()); /* 15.3.1.3.32 */ mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, ARGS_NONE()); /* 15.3.1.3.33 */ @@ -1244,6 +1226,7 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,ARGS_REQ(1)); /* 15.3.1.3.41 */ mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, ARGS_ANY()); /* 15.3.1.3.43 */ mrb_define_method(mrb, krn, "send", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.44 */ + mrb_define_method(mrb, krn, "__send__", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.4 */ mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, ARGS_ANY()); /* 15.3.1.3.45 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, ARGS_NONE()); /* 15.3.1.3.46 */ diff --git a/src/proc.c b/src/proc.c index 21c462493..98f753ac6 100644 --- a/src/proc.c +++ b/src/proc.c @@ -56,20 +56,41 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) return p; } +static inline void +proc_copy(struct RProc *a, struct RProc *b) +{ + a->flags = b->flags; + a->body = b->body; + a->target_class = b->target_class; + a->env = b->env; +} + static mrb_value mrb_proc_initialize(mrb_state *mrb, mrb_value self) { mrb_value blk; mrb_get_args(mrb, "&", &blk); - if (!mrb_nil_p(blk)) { - *mrb_proc_ptr(self) = *mrb_proc_ptr(blk); - } - else { + if (mrb_nil_p(blk)) { /* Calling Proc.new without a block is not implemented yet */ mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); } + else { + proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk)); + } + return self; +} +static mrb_value +mrb_proc_init_copy(mrb_state *mrb, mrb_value self) +{ + mrb_value proc; + + mrb_get_args(mrb, "o", &proc); + if (mrb_type(proc) != MRB_TT_PROC) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } + proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc)); return self; } @@ -91,6 +112,35 @@ mrb_proc_iseq(mrb_state *mrb, struct RProc *p) return p->body.irep->iseq; } +/* 15.3.1.2.6 */ +/* 15.3.1.3.27 */ +/* + * call-seq: + * lambda { |...| block } -> a_proc + * + * Equivalent to <code>Proc.new</code>, except the resulting Proc objects + * check the number of parameters passed when called. + */ +static mrb_value +proc_lambda(mrb_state *mrb, mrb_value self) +{ + mrb_value blk; + struct RProc *p; + + mrb_get_args(mrb, "&", &blk); + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); + } + p = mrb_proc_ptr(blk); + if (!MRB_PROC_STRICT_P(p)) { + struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c); + proc_copy(p2, p); + p2->flags |= MRB_PROC_STRICT; + return mrb_obj_value(p2); + } + return self; +} + void mrb_init_proc(mrb_state *mrb) { @@ -108,10 +158,15 @@ mrb_init_proc(mrb_state *mrb) call_irep->ilen = 1; mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); + MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE()); + mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1)); m = mrb_proc_new(mrb, call_irep); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m); + + mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */ + mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */ } @@ -2143,7 +2143,7 @@ mrb_reg_regsub(mrb_state *mrb, mrb_value str, mrb_value src, struct re_registers break; } else { - mrb_raise(mrb, mrb->eRuntimeError_class, "invalid group name reference format"); + mrb_raise(mrb, E_RUNTIME_ERROR, "invalid group name reference format"); } } diff --git a/src/string.c b/src/string.c index 6392b504c..585edf8a3 100644 --- a/src/string.c +++ b/src/string.c @@ -100,7 +100,7 @@ str_mod_check(mrb_state *mrb, mrb_value str, char *p, mrb_int len) struct RString *s = mrb_str_ptr(str); if (s->ptr != p || s->len != len) { - mrb_raise(mrb, mrb->eRuntimeError_class, "string modified"); + mrb_raise(mrb, E_RUNTIME_ERROR, "string modified"); } } @@ -788,6 +788,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* setup environment for calling method */ proc = m; irep = m->body.irep; + if (!irep) { + mrb->stack[0] = mrb_nil_value(); + goto L_RETURN; + } pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; @@ -1600,7 +1604,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_ERR) { /* Bx raise RuntimeError with message Lit(Bx) */ mrb_value msg = pool[GETARG_Bx(i)]; - mrb_value exc = mrb_exc_new3(mrb, mrb->eRuntimeError_class, msg); + mrb_value exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg); mrb->exc = (struct RObject*)mrb_object(exc); goto L_RAISE; |
