Beispiel #1
0
static void
exc_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream)
{
  mrb_value lastpc;
  mrb_code *code;

  lastpc = mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "lastpc"));
  if (mrb_nil_p(lastpc)) {
    code = NULL;
  } else {
    code = (mrb_code*)mrb_cptr(lastpc);
  }

  output_backtrace(mrb, mrb_fixnum(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "ciidx"))),
                   code, func, stream);
}
Beispiel #2
0
mrb_value
mrb_class_path(mrb_state *mrb, struct RClass *c)
{
  mrb_value path;
  const char *name;
  size_t len;
  mrb_sym classpath = mrb_intern2(mrb, "__classpath__", 13);

  path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
  if (mrb_nil_p(path)) {
    struct RClass *outer = mrb_class_outer_module(mrb, c);
    mrb_sym sym = mrb_class_sym(mrb, c, outer);
    if (sym == 0) {
      return mrb_nil_value();
    }
    else if (outer && outer != mrb->object_class) {
      mrb_value base = mrb_class_path(mrb, outer);
      path = mrb_str_plus(mrb, base, mrb_str_new(mrb, "::", 2));
      name = mrb_sym2name_len(mrb, sym, &len);
      mrb_str_concat(mrb, path, mrb_str_new(mrb, name, len));
    }
    else {
      name = mrb_sym2name_len(mrb, sym, &len);
      path = mrb_str_new(mrb, name, len);
    }
    mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
  }
  return path;
}
Beispiel #3
0
mrb_value
mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
{
    if (obj_iv_p(obj)) {
        return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym);
    }
    return mrb_nil_value();
}
Beispiel #4
0
struct RClass*
mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
{
  mrb_value outer;

  outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__outer__"));
  if (mrb_nil_p(outer)) return 0;
  return mrb_class_ptr(outer);
}
Beispiel #5
0
struct mrb_ffi_type*
rclass_to_mrb_ffi_type(mrb_state *mrb, struct RClass *cls)
{
    struct RClass *cls_ = cls;
    while(cls) {
        mrb_value ffi_type = mrb_obj_iv_get(mrb, (struct RObject*)cls, mrb_intern_cstr(mrb, "@ffi_type"));
        if(mrb_test(ffi_type)) {
            return (struct mrb_ffi_type*)DATA_PTR(ffi_type);
        }
        cls = cls->super;
    }
    mrb_raisef(mrb, E_TYPE_ERROR, "%s cannot convert to C value", mrb_class_name(mrb, cls_));
    return NULL;
}
Beispiel #6
0
static struct RClass*
outer_class(mrb_state *mrb, struct RClass *c)
{
  mrb_value ov;

  ov = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
  if (mrb_nil_p(ov)) return NULL;
  switch (mrb_type(ov)) {
  case MRB_TT_CLASS:
  case MRB_TT_MODULE:
    return mrb_class_ptr(ov);
  default:
    break;
  }
  return NULL;
}
Beispiel #7
0
mrb_sym
mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
{
  mrb_value name;

  name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classid__"));
  if (mrb_nil_p(name)) {
    struct csym_arg arg;

    arg.c = c;
    arg.sym = 0;

    iv_foreach(mrb, outer->iv, csym_i, &arg);
    return arg.sym;
  }
  return SYM2ID(name);
}
Beispiel #8
0
static void
showcallinfo(mrb_state *mrb)
{
  mrb_callinfo *ci;
  mrb_int ciidx;
  const char *filename, *method, *sep;
  int i, line;

  printf("trace:\n");
  ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
  if (ciidx >= mrb->ciend - mrb->cibase)
    ciidx = 10; /* ciidx is broken... */

  for (i = ciidx; i >= 0; i--) {
    ci = &mrb->cibase[i];
    filename = "(unknown)";
    line = -1;

    if (MRB_PROC_CFUNC_P(ci->proc)) {
      continue;
    }
    else {
      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->iseq <= pc && pc < irep->iseq + irep->ilen) {
          line = irep->lines[pc - irep->iseq - 1];
        }
      }
    }
    if (ci->target_class == ci->proc->target_class)
      sep = ".";
    else
      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 : "");
  }
}
Beispiel #9
0
MRB_API void
mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
{
  struct RClass * cls = c;

  while (c) {
    if (c->iv) {
      iv_tbl *t = c->iv;

      if (iv_get(mrb, t, sym, NULL)) {
        mrb_write_barrier(mrb, (struct RBasic*)c);
        iv_put(mrb, t, sym, v);
        return;
      }
    }
    c = c->super;
  }

  if (cls && cls->tt == MRB_TT_SCLASS) {
    mrb_value klass;

    klass = mrb_obj_iv_get(mrb, (struct RObject*)cls,
                           mrb_intern_lit(mrb, "__attached__"));
    switch (mrb_type(klass)) {
    case MRB_TT_CLASS:
    case MRB_TT_MODULE:
    case MRB_TT_SCLASS:
      c = mrb_class_ptr(klass);
      break;
    default:
      c = cls;
      break;
    }
  }
  else{
    c = cls;
  }

  if (!c->iv) {
    c->iv = iv_new(mrb);
  }

  mrb_write_barrier(mrb, (struct RBasic*)c);
  iv_put(mrb, c->iv, sym, v);
}
Beispiel #10
0
static mrb_sym
class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
{
  mrb_value name;

  name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classid__"));
  if (mrb_nil_p(name)) {
    khash_t(iv)* h;
    khiter_t k;
    mrb_value v;

    if (!outer) outer = mrb->object_class;
    h = outer->iv;
    for (k = kh_begin(h); k != kh_end(h); k++) {
      if (!kh_exist(h,k)) continue;
      v = kh_value(h,k);
      if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) {
        return kh_key(h,k);
      }
    }
  }
  return SYM2ID(name);
}
Beispiel #11
0
MRB_API void
mrb_print_backtrace(mrb_state *mrb)
{
  mrb_value backtrace;

  if (!mrb->exc) {
    return;
  }

  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
  if (!mrb_nil_p(backtrace)) {
    print_backtrace(mrb, backtrace);
  }
  else if (mrb->backtrace.n > 0) {
    print_backtrace_saved(mrb);
  }
  else {
    struct print_backtrace_args args;
    args.stream = stderr;
    args.tracehead = TRUE;
    exc_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)&args);
  }
}
Beispiel #12
0
mrb_value
mrb_class_path(mrb_state *mrb, struct RClass *c)
{
  mrb_value path;

  path = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"));
  if (mrb_nil_p(path)) {
    struct RClass *outer = mrb_class_outer_module(mrb, c);
    mrb_sym sym = class_sym(mrb, c, outer);
    if (outer && outer != mrb->object_class) {
      mrb_value base = mrb_class_path(mrb, outer);
      path = mrb_str_plus(mrb, base, mrb_str_new_cstr(mrb, "::"));
      mrb_str_concat(mrb, path, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, sym)));
    }
    else if (sym == 0) {
      return mrb_nil_value();
    }
    else {
      path = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, sym));
    }
    mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"), path);
  }
  return path;
}
Beispiel #13
0
MRB_API mrb_value
mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
{
  struct RClass * cls = c;
  mrb_value v;
  int given = FALSE;

  while (c) {
    if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
      given = TRUE;
    }
    c = c->super;
  }
  if (given) return v;
  if (cls && cls->tt == MRB_TT_SCLASS) {
    mrb_value klass;

    klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,
                           mrb_intern_lit(mrb, "__attached__"));
    c = mrb_class_ptr(klass);
    if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
      given = FALSE;
      while (c) {
        if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
          given = TRUE;
        }
        c = c->super;
      }
      if (given) return v;
    }
  }
  mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
                 mrb_sym2str(mrb, sym), mrb_obj_value(cls));
  /* not reached */
  return mrb_nil_value();
}
Beispiel #14
0
void
mrb_print_backtrace(mrb_state *mrb)
{
#ifdef ENABLE_STDIO
    mrb_callinfo *ci;
    mrb_int ciidx;
    const char *filename, *method, *sep;
    int i, line;

    printf("trace:\n");
    ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
    if (ciidx >= mrb->ciend - mrb->cibase)
        ciidx = 10; /* ciidx is broken... */

    for (i = ciidx; i >= 0; i--) {
        ci = &mrb->cibase[i];
        filename = "(unknown)";
        line = -1;

        if (MRB_PROC_CFUNC_P(ci->proc)) {
            continue;
        }
        else {
            mrb_irep *irep = ci->proc->body.irep;
            if (irep->filename != NULL)
                filename = irep->filename;
            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];
                }
            }
        }
        if (line == -1) continue;
        if (ci->target_class == ci->proc->target_class)
            sep = ".";
        else
            sep = "#";

        method = mrb_sym2name(mrb, ci->mid);
        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);
        }
    }
#endif
}
Beispiel #15
0
static mrb_bool
have_backtrace(mrb_state *mrb, struct RObject *exc)
{
  return !mrb_nil_p(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "backtrace")));
}