summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/value.h87
-rw-r--r--include/mruby/variable.h1
-rw-r--r--src/kernel.c7
-rw-r--r--src/variable.c15
-rw-r--r--src/vm.c1
-rw-r--r--tools/mruby/mruby.c33
6 files changed, 97 insertions, 47 deletions
diff --git a/include/mruby/value.h b/include/mruby/value.h
index 90c011a7e..ab56c9795 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -17,25 +17,26 @@ enum mrb_vtype {
MRB_TT_SYMBOL, /* 4 */
MRB_TT_UNDEF, /* 5 */
MRB_TT_FLOAT, /* 6 */
- MRB_TT_MAIN, /* 7 */
- MRB_TT_OBJECT, /* 8 */
- MRB_TT_CLASS, /* 9 */
- MRB_TT_MODULE, /* 10 */
- MRB_TT_ICLASS, /* 11 */
- MRB_TT_SCLASS, /* 12 */
- MRB_TT_PROC, /* 13 */
- MRB_TT_ARRAY, /* 14 */
- MRB_TT_HASH, /* 15 */
- MRB_TT_STRING, /* 16 */
- MRB_TT_RANGE, /* 17 */
- MRB_TT_REGEX, /* 18 */
- MRB_TT_STRUCT, /* 19 */
- MRB_TT_EXCEPTION, /* 20 */
- MRB_TT_MATCH, /* 21 */
- MRB_TT_FILE, /* 22 */
- MRB_TT_ENV, /* 23 */
- MRB_TT_DATA, /* 24 */
- MRB_TT_MAXDEFINE /* 25 */
+ MRB_TT_VOIDP, /* 7 */
+ MRB_TT_MAIN, /* 8 */
+ MRB_TT_OBJECT, /* 9 */
+ MRB_TT_CLASS, /* 10 */
+ MRB_TT_MODULE, /* 11 */
+ MRB_TT_ICLASS, /* 12 */
+ MRB_TT_SCLASS, /* 13 */
+ MRB_TT_PROC, /* 14 */
+ MRB_TT_ARRAY, /* 15 */
+ MRB_TT_HASH, /* 16 */
+ MRB_TT_STRING, /* 17 */
+ MRB_TT_RANGE, /* 18 */
+ MRB_TT_REGEX, /* 19 */
+ MRB_TT_STRUCT, /* 20 */
+ MRB_TT_EXCEPTION, /* 21 */
+ MRB_TT_MATCH, /* 22 */
+ MRB_TT_FILE, /* 23 */
+ MRB_TT_ENV, /* 24 */
+ MRB_TT_DATA, /* 25 */
+ MRB_TT_MAXDEFINE /* 26 */
};
typedef struct mrb_value {
@@ -78,24 +79,25 @@ enum mrb_vtype {
MRB_TT_SYMBOL, /* 5 */
MRB_TT_UNDEF, /* 6 */
MRB_TT_FLOAT, /* 7 */
- MRB_TT_MAIN, /* 8 */
- MRB_TT_OBJECT, /* 9 */
- MRB_TT_CLASS, /* 10 */
- MRB_TT_MODULE, /* 11 */
- MRB_TT_ICLASS, /* 12 */
- MRB_TT_SCLASS, /* 13 */
- MRB_TT_PROC, /* 14 */
- MRB_TT_ARRAY, /* 15 */
- MRB_TT_HASH, /* 16 */
- MRB_TT_STRING, /* 17 */
- MRB_TT_RANGE, /* 18 */
- MRB_TT_REGEX, /* 19 */
- MRB_TT_STRUCT, /* 20 */
- MRB_TT_EXCEPTION, /* 21 */
- MRB_TT_MATCH, /* 22 */
- MRB_TT_FILE, /* 23 */
- MRB_TT_ENV, /* 24 */
- MRB_TT_DATA, /* 25 */
+ MRB_TT_VOIDP, /* 8 */
+ MRB_TT_MAIN, /* 9 */
+ MRB_TT_OBJECT, /* 10 */
+ MRB_TT_CLASS, /* 11 */
+ MRB_TT_MODULE, /* 12 */
+ MRB_TT_ICLASS, /* 13 */
+ MRB_TT_SCLASS, /* 14 */
+ MRB_TT_PROC, /* 15 */
+ MRB_TT_ARRAY, /* 16 */
+ MRB_TT_HASH, /* 17 */
+ MRB_TT_STRING, /* 18 */
+ MRB_TT_RANGE, /* 19 */
+ MRB_TT_REGEX, /* 20 */
+ MRB_TT_STRUCT, /* 21 */
+ MRB_TT_EXCEPTION, /* 22 */
+ MRB_TT_MATCH, /* 23 */
+ MRB_TT_FILE, /* 24 */
+ MRB_TT_ENV, /* 25 */
+ MRB_TT_DATA, /* 26 */
MRB_TT_MAXDEFINE /* 27 */
};
@@ -149,6 +151,7 @@ mrb_float_value(mrb_float f)
#define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym
#define mrb_object(o) ((struct RBasic *) (o).value.p)
+#define mrb_voidp(o) (o).value.p
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
@@ -157,6 +160,7 @@ mrb_float_value(mrb_float f)
#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
+#define mrb_voidp_p(o) (mrb_type(o) == MRB_TT_VOIDP)
#define mrb_test(o) (mrb_type(o) != MRB_TT_FALSE)
#define MRB_OBJECT_HEADER \
@@ -229,6 +233,15 @@ mrb_obj_value(void *p)
}
static inline mrb_value
+mrb_voidp_value(void *p)
+{
+ mrb_value v;
+
+ MRB_SET_VALUE(v, MRB_TT_VOIDP, value.p, p);
+ return v;
+}
+
+static inline mrb_value
mrb_false_value(void)
{
mrb_value v;
diff --git a/include/mruby/variable.h b/include/mruby/variable.h
index 5126315c4..7189ef690 100644
--- a/include/mruby/variable.h
+++ b/include/mruby/variable.h
@@ -41,6 +41,7 @@ int mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
int mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
+void mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym);
void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v);
int mrb_iv_defined(mrb_state*, mrb_value, mrb_sym);
diff --git a/src/kernel.c b/src/kernel.c
index 85eedc7ba..5e8a2f5aa 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -920,8 +920,9 @@ mrb_obj_public_methods(mrb_state *mrb, mrb_value self)
mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
- mrb_value a[2];
+ mrb_value a[2], exc;
int argc;
+
argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
switch (argc) {
@@ -936,7 +937,9 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
}
/* fall through */
default:
- mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, a));
+ exc = mrb_make_exception(mrb, argc, a);
+ mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern(mrb, "lastpc"), mrb_voidp_value(mrb->ci->pc));
+ mrb_exc_raise(mrb, exc);
}
return mrb_nil_value(); /* not reached */
}
diff --git a/src/variable.c b/src/variable.c
index 6907a8e2a..992663408 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -461,6 +461,21 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
}
void
+mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+{
+ iv_tbl *t = obj->iv;
+
+ if (!t) {
+ t = obj->iv = iv_new(mrb);
+ }
+ else if (iv_get(mrb, t, sym, &v)) {
+ return;
+ }
+ mrb_write_barrier(mrb, (struct RBasic*)obj);
+ iv_put(mrb, t, sym, v);
+}
+
+void
mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v)
{
if (obj_iv_p(obj)) {
diff --git a/src/vm.c b/src/vm.c
index bee99515e..92861d48c 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1151,6 +1151,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
int eidx;
L_RAISE:
+ mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern(mrb, "lastpc"), mrb_voidp_value(pc));
ci = mrb->ci;
eidx = mrb->ci->eidx;
if (ci == mrb->cibase) goto L_STOP;
diff --git a/tools/mruby/mruby.c b/tools/mruby/mruby.c
index d3ea924c7..99af7bc5d 100644
--- a/tools/mruby/mruby.c
+++ b/tools/mruby/mruby.c
@@ -188,8 +188,15 @@ showcallinfo(mrb_state *mrb)
mrb_irep *irep = ci->proc->body.irep;
if (irep->filename != NULL)
filename = irep->filename;
- if (irep->lines != NULL && i+1 <= ciidx) {
- mrb_code *pc = mrb->cibase[i+1].pc;
+ if (irep->lines != NULL) {
+ mrb_code *pc;
+
+ if (i+1 <= ciidx) {
+ pc = mrb->cibase[i+1].pc;
+ }
+ else {
+ pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "lastpc")));
+ }
if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
line = irep->lines[pc - irep->iseq - 1];
}
@@ -201,12 +208,22 @@ showcallinfo(mrb_state *mrb)
sep = "#";
method = mrb_sym2name(mrb, ci->mid);
- printf("\t[%d] %s:%d%s%s%s%s\n",
- i, filename, line,
- method ? ":in " : "",
- method ? mrb_class_name(mrb, ci->proc->target_class) : "",
- method ? sep : "",
- method ? method : "");
+ if (method) {
+ const char *cn = mrb_class_name(mrb, ci->proc->target_class);
+
+ if (cn) {
+ printf("\t[%d] %s:%d:in %s%s%s\n",
+ i, filename, line, cn, sep, method);
+ }
+ else {
+ printf("\t[%d] %s:%d:in %s\n",
+ i, filename, line, method);
+ }
+ }
+ else {
+ printf("\t[%d] %s:%d\n",
+ i, filename, line);
+ }
}
}