diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backtrace.c | 13 | ||||
| -rw-r--r-- | src/class.c | 13 | ||||
| -rw-r--r-- | src/codegen.c | 4 | ||||
| -rw-r--r-- | src/error.c | 12 | ||||
| -rw-r--r-- | src/numeric.c | 114 | ||||
| -rw-r--r-- | src/variable.c | 26 | ||||
| -rw-r--r-- | src/vm.c | 33 |
7 files changed, 82 insertions, 133 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index 4ad792a5e..54927ec00 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -77,18 +77,21 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun if (MRB_PROC_CFUNC_P(ci->proc)) { continue; } - if(!MRB_PROC_CFUNC_P(ci->proc)) { + else { mrb_irep *irep = ci->proc->body.irep; mrb_code *pc; - if (i+1 <= ciidx) { - pc = mrb->c->cibase[i+1].pc; + if (mrb->c->cibase[i].err) { + pc = mrb->c->cibase[i].err; + } + else if (i+1 <= ciidx) { + pc = mrb->c->cibase[i+1].pc - 1; } else { pc = (mrb_code*)mrb_cptr(mrb_obj_iv_get(mrb, exc, mrb_intern2(mrb, "lastpc", 6))); } - filename = mrb_debug_get_filename(irep, pc - irep->iseq - 1); - line = mrb_debug_get_line(irep, pc - irep->iseq - 1); + filename = mrb_debug_get_filename(irep, pc - irep->iseq); + line = mrb_debug_get_line(irep, pc - irep->iseq); } if (line == -1) continue; if (ci->target_class == ci->proc->target_class) diff --git a/src/class.c b/src/class.c index 4b8f2de10..2745f9820 100644 --- a/src/class.c +++ b/src/class.c @@ -1828,6 +1828,18 @@ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) return val; } +mrb_value +mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym sym; + + mrb_get_args(mrb, "n", &sym); + mrb_name_error(mrb, sym, "uninitialized constant %S", + mrb_sym2str(mrb, sym)); + /* not reached */ + return mrb_nil_value(); +} + static mrb_value mrb_mod_s_constants(mrb_state *mrb, mrb_value mod) { @@ -1921,6 +1933,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */ mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_NONE()); /* 15.2.2.4.24 */ mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */ + mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */ mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); diff --git a/src/codegen.c b/src/codegen.c index bb479842c..578fb96ac 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -646,7 +646,9 @@ scope_body(codegen_scope *s, node *tree) genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); } else { - genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL), NOVAL); + pop(); + genop_peep(scope, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + push(); } } scope_finish(scope); diff --git a/src/error.c b/src/error.c index 4ce2b4ade..10ba6170f 100644 --- a/src/error.c +++ b/src/error.c @@ -194,14 +194,16 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) mrb_code *pc = ci->pc; mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase)); - ci--; while (ci >= mrb->c->cibase) { - if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { + mrb_code *err = ci->err; + + if (!err && pc) err = pc - 1; + if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { mrb_irep *irep = ci->proc->body.irep; - int32_t const line = mrb_debug_get_line(irep, pc - irep->iseq - 1); - char const* file = mrb_debug_get_filename(irep, pc - irep->iseq - 1); - if(line != -1 && file) { + int32_t const line = mrb_debug_get_line(irep, err - irep->iseq); + char const* file = mrb_debug_get_filename(irep, err - irep->iseq); + if (line != -1 && file) { mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "file", 4), mrb_str_new_cstr(mrb, file)); mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "line", 4), mrb_fixnum_value(line)); return; diff --git a/src/numeric.c b/src/numeric.c index c309abf89..ccb67bcc3 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -42,38 +42,6 @@ mrb_to_flo(mrb_state *mrb, mrb_value val) } /* - * call-seq: - * +num -> num - * - * Unary Plus---Returns the receiver's value. - */ - -static mrb_value -num_uplus(mrb_state *mrb, mrb_value num) -{ - return num; -} - -/* - * call-seq: - * -num -> numeric - * - * Unary Minus---Returns the receiver's value, negated. - */ - -static mrb_value -num_uminus(mrb_state *mrb, mrb_value num) -{ - return mrb_float_value(mrb, (mrb_float)0 - mrb_to_flo(mrb, num)); -} - -static mrb_value -fix_uminus(mrb_state *mrb, mrb_value num) -{ - return mrb_fixnum_value(0 - mrb_fixnum(num)); -} - -/* * call-seq: * * num ** other -> num @@ -131,27 +99,6 @@ num_div(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); } -/* - * call-seq: - * num.abs -> numeric - * num.magnitude -> numeric - * - * Returns the absolute value of <i>num</i>. - * - * 12.abs #=> 12 - * (-34.56).abs #=> 34.56 - * -34.56.abs #=> 34.56 - */ - -static mrb_value -num_abs(mrb_state *mrb, mrb_value num) -{ - if (mrb_to_flo(mrb, num) < 0) { - return num_uminus(mrb, num); - } - return num; -} - /******************************************************************** * * Document-class: Float @@ -695,42 +642,6 @@ int_to_i(mrb_state *mrb, mrb_value num) return num; } -/* 15.2.8.3.21 */ -/* - * call-seq: - * fixnum.next -> integer - * fixnum.succ -> integer - * - * Returns the <code>Integer</code> equal to <i>int</i> + 1. - * - * 1.next #=> 2 - * (-1).next #=> 0 - */ - -static mrb_value -fix_succ(mrb_state *mrb, mrb_value num) -{ - return mrb_fixnum_value(mrb_fixnum(num)+1); -} - -/* 15.2.8.3.19 */ -/* - * call-seq: - * int.next -> integer - * int.succ -> integer - * - * Returns the <code>Integer</code> equal to <i>int</i> + 1. - * - * 1.next #=> 2 - * (-1).next #=> 0 - */ -static mrb_value -int_succ(mrb_state *mrb, mrb_value num) -{ - if (mrb_fixnum_p(num)) return fix_succ(mrb, num); - return mrb_funcall(mrb, num, "+", 1, mrb_fixnum_value(1)); -} - #define SQRT_INT_MAX ((mrb_int)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2)) /*tests if N*N would overflow*/ #define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX)) @@ -873,6 +784,21 @@ fix_divmod(mrb_state *mrb, mrb_value x) } } +static mrb_value +flo_divmod(mrb_state *mrb, mrb_value x) +{ + mrb_value y; + mrb_float div, mod; + mrb_value a, b; + + mrb_get_args(mrb, "o", &y); + + flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); + a = mrb_float_value(mrb, (mrb_int)div); + b = mrb_float_value(mrb, mod); + return mrb_assoc_new(mrb, a, b); +} + /* 15.2.8.3.7 */ /* * call-seq: @@ -1359,14 +1285,10 @@ mrb_init_numeric(mrb_state *mrb) /* Numeric Class */ numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); - mrb_include_module(mrb, numeric, mrb_class_get(mrb, "Comparable")); - mrb_define_method(mrb, numeric, "+@", num_uplus, MRB_ARGS_REQ(1)); /* 15.2.7.4.1 */ - mrb_define_method(mrb, numeric, "-@", num_uminus, MRB_ARGS_REQ(1)); /* 15.2.7.4.2 */ mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */ mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ - mrb_define_method(mrb, numeric, "abs", num_abs, MRB_ARGS_NONE()); /* 15.2.7.4.3 */ mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ /* Integer Class */ @@ -1374,11 +1296,10 @@ mrb_init_numeric(mrb_state *mrb) mrb_undef_class_method(mrb, integer, "new"); mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); - fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer); + fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer); mrb_define_method(mrb, fixnum, "+", fix_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ mrb_define_method(mrb, fixnum, "-", fix_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */ - mrb_define_method(mrb, fixnum, "-@", fix_uminus, MRB_ARGS_REQ(1)); /* 15.2.7.4.2 */ mrb_define_method(mrb, fixnum, "*", fix_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */ mrb_define_method(mrb, fixnum, "%", fix_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */ mrb_define_method(mrb, fixnum, "==", fix_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */ @@ -1390,8 +1311,6 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ mrb_define_method(mrb, fixnum, "eql?", num_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ mrb_define_method(mrb, fixnum, "hash", flo_hash, MRB_ARGS_NONE()); /* 15.2.8.3.18 */ - mrb_define_method(mrb, fixnum, "next", int_succ, MRB_ARGS_NONE()); /* 15.2.8.3.19 */ - mrb_define_method(mrb, fixnum, "succ", fix_succ, MRB_ARGS_NONE()); /* 15.2.8.3.21 */ mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); @@ -1414,6 +1333,7 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE()); mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */ + mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "to_s", flo_to_s, MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */ mrb_define_method(mrb, fl, "inspect", flo_to_s, MRB_ARGS_NONE()); diff --git a/src/variable.c b/src/variable.c index f2a474201..ffad3dad3 100644 --- a/src/variable.c +++ b/src/variable.c @@ -867,7 +867,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) mrb_value v; iv_tbl *t; mrb_bool retry = 0; - mrb_sym cm; + mrb_value name; L_RETRY: while (c) { @@ -883,19 +883,8 @@ L_RETRY: retry = 1; goto L_RETRY; } - c = base; - cm = mrb_intern2(mrb, "const_missing", 13); - while (c) { - if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) { - mrb_value name = mrb_symbol_value(sym); - return mrb_funcall_argv(mrb, mrb_obj_value(c), cm, 1, &name); - } - c = c->super; - } - mrb_name_error(mrb, sym, "uninitialized constant %S", - mrb_sym2str(mrb, sym)); - /* not reached */ - return mrb_nil_value(); + name = mrb_symbol_value(sym); + return mrb_funcall_argv(mrb, mrb_obj_value(base), mrb_intern2(mrb, "const_missing", 13), 1, &name); } mrb_value @@ -1031,6 +1020,15 @@ mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) iv_put(mrb, t, sym, v); } +void +mrb_gv_remove(mrb_state *mrb, mrb_sym sym) +{ + if (!mrb->globals) { + return; + } + iv_del(mrb, mrb->globals, sym, NULL); +} + static int gv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) { @@ -75,7 +75,12 @@ stack_clear(mrb_value *from, size_t count) const mrb_value mrb_value_zero = { { 0 } }; while (count-- > 0) { +#ifndef MRB_NAN_BOXING *from++ = mrb_value_zero; +#else + SET_NIL_VALUE(*from); + from++; +#endif } } @@ -156,15 +161,7 @@ stack_extend(mrb_state *mrb, int room, int keep) } if (room > keep) { -#ifndef MRB_NAN_BOXING stack_clear(&(mrb->c->stack[keep]), room - keep); -#else - struct mrb_context *c = mrb->c; - int i; - for (i=keep; i<room; i++) { - SET_NIL_VALUE(c->stack[i]); - } -#endif } } @@ -229,6 +226,8 @@ cipush(mrb_state *mrb) ci->eidx = eidx; ci->ridx = ridx; ci->env = 0; + ci->pc = 0; + return ci; } @@ -512,8 +511,9 @@ argnum_error(mrb_state *mrb, int num) mrb->exc = mrb_obj_ptr(exc); } +#define ERR_PC_HOOK(mrb, pc) mrb->c->ci->err = pc; #ifdef ENABLE_DEBUG -#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); +#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else #define CODE_FETCH_HOOK(mrb, irep, pc, regs) #endif @@ -596,6 +596,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) stack_init(mrb); } stack_extend(mrb, irep->nregs, irep->nregs); + mrb->c->ci->err = pc; mrb->c->ci->proc = proc; mrb->c->ci->nregs = irep->nregs + 1; regs = mrb->c->stack; @@ -687,6 +688,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETCV) { /* A B R(A) := ivget(Sym(B)) */ + ERR_PC_HOOK(mrb, pc); regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]); NEXT; } @@ -699,7 +701,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETCONST) { /* A B R(A) := constget(Sym(B)) */ - regs[GETARG_A(i)] = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]); + mrb_value val; + + ERR_PC_HOOK(mrb, pc); + val = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]); + regs = mrb->c->stack; + regs[GETARG_A(i)] = val; NEXT; } @@ -711,9 +718,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETMCNST) { /* A B C R(A) := R(C)::Sym(B) */ + mrb_value val; int a = GETARG_A(i); - regs[a] = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]); + ERR_PC_HOOK(mrb, pc); + val = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]); + regs = mrb->c->stack; + regs[a] = val; NEXT; } |
