예제 #1
0
파일: codedump.c 프로젝트: cremno/mruby
static int
print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre)
{
  size_t i;

  if (n == 0) return 0;

  for (i=0; i+1<irep->nlocals; i++) {
    if (irep->lv[i].r == n) {
      mrb_sym sym = irep->lv[i].name;
      if (pre) printf(" ");
      printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym));
      return 1;
    }
  }
  return 0;
}
예제 #2
0
파일: error.c 프로젝트: Zyxwvu/mruby
void
mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
{
  mrb_value exc, argv[2];
  va_list args;
  char buf[256];

  va_start(args, fmt);
  //argv[0] = mrb_vsprintf(fmt, args);
  vsnprintf(buf, 256, fmt, args);
  argv[0] = mrb_str_new(mrb, buf, strlen(buf));
  va_end(args);

  argv[1] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
  exc = mrb_class_new_instance(mrb, 2, argv, E_NAME_ERROR);
  mrb_exc_raise(mrb, exc);
}
예제 #3
0
파일: mruby.c 프로젝트: daniel-higa/mruby
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 : "");
  }
}
예제 #4
0
파일: marshal.cpp 프로젝트: cjv123/RPG
static struct RClass *
mrb_class_from_path(mrb_state *mrb, mrb_value path)
{
	char *path_s;
	switch (path.tt)
	{
	case MRB_TT_SYMBOL :
		path_s = (char*) mrb_sym2name(mrb, mrb_symbol(path));
		break;
	case MRB_TT_STRING :
		path_s = (char*) RSTRING_PTR(path);
		break;
	default:
		throw Exception(Exception::ArgumentError, "dump format error for symbol");
	}

	/* If a symbol contains any colons, mrb_sym2name
	 * will return the string with "s around it
	 * (e.g. :Mod::Class => :"Mod::Class"),
	 * so we need to skip those. */
	if (path_s[0] == '\"')
		path_s++;

	char *p, *pbgn;
	mrb_value klass = mrb_obj_value(mrb->object_class);

	p = pbgn = path_s;

	while (*p && *p != '\"')
	{
		while (*p && *p != ':' && *p != '\"') p++;

		mrb_sym sym = mrb_intern(mrb, pbgn, p-pbgn);
		klass = mrb_const_get(mrb, klass, sym);

		if (p[0] == ':')
		{
			if (p[1] != ':')
				return 0;
			p += 2;
			pbgn = p;
		}
	}

	return (struct RClass*) mrb_obj_ptr(klass);
}
예제 #5
0
static mrb_value
inspect_struct(mrb_state *mrb, mrb_value s, mrb_value dummy, int recur)
{
    const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s));
    mrb_value members, str = mrb_str_new2(mrb, "#<struct ");
    mrb_value *ptr, *ptr_members;
    long i, len;

    if (cn) {
      mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn));
    }
    if (recur) {
      return mrb_str_cat2(mrb, str, ":...>");
    }

    members = mrb_struct_members(mrb, s);
    ptr_members = RARRAY_PTR(members);
    ptr = RSTRUCT_PTR(s);
    len = RSTRUCT_LEN(s);
    for (i=0; i<len; i++) {
      mrb_value slot;
      mrb_sym id;

      if (i > 0) {
          mrb_str_cat2(mrb, str, ", ");
      }
      else if (cn) {
          mrb_str_cat2(mrb, str, " ");
      }
      slot = ptr_members[i];
      id = SYM2ID(slot);
      if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
        //mrb_str_append(str, mrb_id2str(id));
        mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)));
      }
      else {
          mrb_str_append(mrb, str, mrb_inspect(mrb, slot));
      }
      mrb_str_cat2(mrb, str, "=");
      mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i]));
    }
    mrb_str_cat2(mrb, str, ">");

    return str;
}
예제 #6
0
파일: struct.c 프로젝트: charliesome/mruby
static mrb_value
mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id)
{
    mrb_value *ptr, members, *ptr_members;
    long i, len;

    ptr = RSTRUCT_PTR(s);
    members = mrb_struct_members(mrb, s);
    ptr_members = RARRAY_PTR(members);
    len = RARRAY_LEN(members);
    for (i=0; i<len; i++) {
      if (SYM2ID(ptr_members[i]) == id) {
          return ptr[i];
      }
    }
    mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
    return mrb_nil_value();            /* not reached */
}
예제 #7
0
파일: vm.c 프로젝트: kayakjang/mruby
static void
argnum_error(mrb_state *mrb, int num)
{
  char buf[256];
  mrb_value exc;

  if (mrb->ci->mid) {
    snprintf(buf, 256, "'%s': wrong number of arguments (%d for %d)",
	     mrb_sym2name(mrb, mrb->ci->mid),
	     mrb->ci->argc, num);
  }
  else {
    snprintf(buf, 256, "wrong number of arguments (%d for %d)",
	     mrb->ci->argc, num);
  }
  exc = mrb_exc_new(mrb, E_ARGUMENT_ERROR, buf, strlen(buf));
  mrb->exc = mrb_object(exc);
}
예제 #8
0
파일: struct.c 프로젝트: chancelab/mruby
static mrb_value
mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id)
{
  mrb_value *ptr, members, *ptr_members;
  mrb_int i, len;

  ptr = RSTRUCT_PTR(s);
  members = mrb_struct_members(mrb, s);
  ptr_members = RARRAY_PTR(members);
  len = RARRAY_LEN(members);
  for (i=0; i<len; i++) {
    if (mrb_symbol(ptr_members[i]) == id) {
      return ptr[i];
    }
  }
  mrb_raisef(mrb, E_NAME_ERROR, "no member '%s' in struct", mrb_sym2name(mrb, id));
  return mrb_nil_value();       /* not reached */
}
예제 #9
0
파일: vm.c 프로젝트: dpoetonwheels/mruby
static void
argnum_error(mrb_state *mrb, int num)
{
  char buf[256];
  int len;
  mrb_value exc;

  if (mrb->ci->mid) {
    len = snprintf(buf, sizeof(buf), "'%s': wrong number of arguments (%d for %d)",
		   mrb_sym2name(mrb, mrb->ci->mid),
		   mrb->ci->argc, num);
  }
  else {
    len = snprintf(buf, sizeof(buf), "wrong number of arguments (%d for %d)",
		   mrb->ci->argc, num);
  }
  exc = mrb_exc_new(mrb, E_ARGUMENT_ERROR, buf, len);
  mrb->exc = (struct RObject*)mrb_object(exc);
}
예제 #10
0
파일: dump.c 프로젝트: Zyxwvu/mruby
static int
write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
{
  int sym_no;
  char *buf_top = buf;
  char *char_buf;
  uint16_t buf_size =0;

  buf_size = MRB_DUMP_DEFAULT_STR_LEN;
  if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
    goto error_exit;

  buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */

  for (sym_no = 0; sym_no < irep->slen; sym_no++) {
    const char * name;
    uint16_t nlen =0;

    if (irep->syms[sym_no] != 0) {
      name = mrb_sym2name(mrb, irep->syms[sym_no]);
      nlen = str_dump_len((char*)name, strlen(name), type);
      if ( nlen > buf_size - 1) {
        buf_size = nlen + 1;
        if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
          goto error_exit;
      }
      memset(char_buf, 0, buf_size);
      str_dump((char*)name, char_buf, strlen(name), type);

      buf += uint16_dump(nlen, buf, type); /* length of symbol name */
      memcpy(buf, char_buf, nlen); /* symbol name */
      buf += nlen;
    }
    else {
      buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */
    }
  }

error_exit:
  if (char_buf)
    mrb_free(mrb, char_buf);
  return (int)(buf - buf_top);
}
예제 #11
0
struct RClass *
mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
{
  struct RClass * c;
  mrb_sym id = mrb_intern(mrb, name);

  if (mrb_const_defined_at(mrb, outer, id)) {
    c = mrb_class_from_sym(mrb, outer, id);
    if (c->tt != MRB_TT_MODULE) {
        mrb_raise(mrb, E_TYPE_ERROR, "%s is not a module", mrb_sym2name(mrb, id));
    }
    return c;
  }
  c = mrb_module_new(mrb);
  setup_class(mrb, mrb_obj_value(outer), c, id);
  mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));

  return c;
}
예제 #12
0
파일: struct.c 프로젝트: charliesome/mruby
mrb_value
mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
{
    mrb_value members, slot, *ptr, *ptr_members;
    long i, len;

    ptr = RSTRUCT_PTR(obj);
    members = mrb_struct_members(mrb, obj);
    ptr_members = RARRAY_PTR(members);
    slot = mrb_symbol_value(id);
    len = RARRAY_LEN(members);
    for (i=0; i<len; i++) {
      if (mrb_obj_equal(mrb, ptr_members[i], slot)) {
          return ptr[i];
      }
    }
    mrb_name_error(mrb, id, "%s is not struct member", mrb_sym2name(mrb, id));
    return mrb_nil_value();            /* not reached */
}
예제 #13
0
파일: variable.c 프로젝트: koie/mruby
mrb_value
mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym)
{
    struct RClass * cls = c;

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

            if (iv_get(mrb, t, sym, &v))
                return v;
        }
        c = c->super;
    }
    mrb_raisef(mrb, E_NAME_ERROR, "uninitialized class variable %s in %s",
               mrb_sym2name(mrb, sym), mrb_class_name(mrb, cls));
    /* not reached */
    return mrb_nil_value();
}
예제 #14
0
mrb_value
mrb_struct_define(mrb_state *mrb, const char *name, ...)
{
    va_list ar;
    mrb_value nm, ary;
    char *mem;

    if (!name) nm = mrb_nil_value();
    else nm = mrb_str_new2(mrb, name);
    ary = mrb_ary_new(mrb);

    va_start(ar, name);
    while ((mem = va_arg(ar, char*)) != 0) {
      mrb_sym slot = mrb_intern(mrb, mem);
      mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, slot)));
    }
    va_end(ar);

    return make_struct(mrb, nm, ary, struct_class(mrb));
}
예제 #15
0
파일: error.c 프로젝트: Zyxwvu/mruby
void
error_pos(void)
{
#if 0
  const char *sourcefile = mrb_sourcefile();
  int sourceline = mrb_sourceline();

  if (sourcefile) {
    if (sourceline == 0) {
      warn_printf("%s", sourcefile);
    }
    else if (mrb_frame_callee()) {
      warn_printf("%s:%d:in `%s'", sourcefile, sourceline,
                mrb_sym2name(mrb, mrb_frame_callee()));
    }
    else {
      warn_printf("%s:%d", sourcefile, sourceline);
    }
  }
#endif
}
예제 #16
0
static mrb_value
mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
{
    mrb_value members, slot, *ptr, *ptr_members;
    long i, len;

    members = mrb_struct_members(mrb, obj);
    ptr_members = RARRAY_PTR(members);
    len = RARRAY_LEN(members);
    mrb_struct_modify(obj);
    ptr = RSTRUCT_PTR(obj);
    for (i=0; i<len; i++) {
      slot = ptr_members[i];
      if (mrb_id_attrset(SYM2ID(slot)) == 0/*rb_frame_this_func(mrb)*/) {
          return ptr[i] = val;
      }
    }
    mrb_name_error(mrb, 0/*rb_frame_this_func(mrb)*/, "`%s' is not a struct member",
              mrb_sym2name(mrb, 0/*rb_frame_this_func(mrb)*/));
    return mrb_nil_value();            /* not reached */
}
예제 #17
0
파일: class.c 프로젝트: charliesome/mruby
struct RClass*
mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
{
  struct RClass *c, *s;

  if (mrb_const_defined(mrb, outer, id)) {
    mrb_value v = mrb_const_get(mrb, outer, id);

    mrb_check_type(mrb, v, MRB_TT_CLASS);
    c = mrb_class_ptr(v);
    if (!mrb_nil_p(super)) {
      if (mrb_type(super) != MRB_TT_CLASS) {
        mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
      }

      if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) {
        mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id));
      }
    }

    return c;
  }

  if (!mrb_nil_p(super)) {
    if (mrb_type(super) != MRB_TT_CLASS) {
      mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
    }
    s = mrb_class_ptr(super);
  }
  else {
    s = mrb->object_class;
  }

  c = mrb_class_new(mrb, s);
  setup_class(mrb, outer, c, id);
  mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));

  return c;
}
예제 #18
0
파일: kernel.c 프로젝트: beeplove/mruby
/*
 *  call-seq:
 *     obj.instance_variables    -> array
 *
 *  Returns an array of instance variable names for the receiver. Note
 *  that simply defining an accessor does not create the corresponding
 *  instance variable.
 *
 *     class Fred
 *       attr_accessor :a1
 *       def initialize
 *         @iv = 3
 *       end
 *     end
 *     Fred.new.instance_variables   #=> [:@iv]
 */
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
    mrb_value ary;
    kh_iv_t *h = RCLASS_IV_TBL(self);
    int i;
    const char* p;

    ary = mrb_ary_new(mrb);
    if (h) {
      for (i=0;i<kh_end(h);i++) {
        if (kh_exist(h, i)) {
          p = mrb_sym2name(mrb, kh_key(h,i));
          if (*p == '@') {
            if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
              mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
          }
        }
      }
    }
    return ary;
}
예제 #19
0
static mrb_value mrb_vedis_append_s(mrb_state *mrb, mrb_value key_obj, mrb_value val_obj, vedis *vstore)
{
    int ret;
    const char *key = NULL;

    switch (mrb_type(key_obj)) {
        case MRB_TT_STRING:
            key = RSTRING_PTR(key_obj);
            break;
        case MRB_TT_SYMBOL:
            key = mrb_sym2name(mrb, mrb_obj_to_sym(mrb, key_obj));
            break;
        default:
            mrb_raise(mrb, E_RUNTIME_ERROR, "vedis key type is string or symbol");
    }
    val_obj = mrb_obj_as_string(mrb, val_obj);
    ret = vedis_kv_append(vstore, key, strlen(key), RSTRING_PTR(val_obj), RSTRING_LEN(val_obj));
    if (ret != VEDIS_OK) {
        mrb_vedis_error(mrb, vstore, 0);
    }
    return mrb_true_value();
}
예제 #20
0
파일: class.c 프로젝트: AndreOF/ArangoDB
/*
 *  call-seq:
 *     obj.method_missing(symbol [, *args] )   -> result
 *
 *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
 *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
 *  are any arguments that were passed to it. By default, the interpreter
 *  raises an error when this method is called. However, it is possible
 *  to override the method to provide more dynamic behavior.
 *  If it is decided that a particular method should not be handled, then
 *  <i>super</i> should be called, so that ancestors can pick up the
 *  missing method.
 *  The example below creates
 *  a class <code>Roman</code>, which responds to methods with names
 *  consisting of roman numerals, returning the corresponding integer
 *  values.
 *
 *     class Roman
 *       def romanToInt(str)
 *         # ...
 *       end
 *       def method_missing(methId)
 *         str = methId.id2name
 *         romanToInt(str)
 *       end
 *     end
 *
 *     r = Roman.new
 *     r.iv      #=> 4
 *     r.xxiii   #=> 23
 *     r.mm      #=> 2000
 */
static mrb_value
mrb_bob_missing(mrb_state *mrb, mrb_value mod)
{
  mrb_value name, *a;
  int alen;
  mrb_value inspect;

  mrb_get_args(mrb, "o*", &name, &a, &alen);
  if (!mrb_symbol_p(name)) {
    mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol");
  }

  inspect = mrb_funcall(mrb, mod, "inspect", 0);
  if (RSTRING_LEN(inspect) > 64) {
    inspect = mrb_any_to_s(mrb, mod);
  }

  mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%s' for %s",
      mrb_sym2name(mrb, mrb_symbol(name)), RSTRING_PTR(inspect));
  /* not reached */
  return mrb_nil_value();
}
예제 #21
0
파일: kernel.c 프로젝트: beeplove/mruby
/*
 *  call-seq:
 *     obj.remove_instance_variable(symbol)    -> obj
 *
 *  Removes the named instance variable from <i>obj</i>, returning that
 *  variable's value.
 *
 *     class Dummy
 *       attr_reader :var
 *       def initialize
 *         @var = 99
 *       end
 *       def remove
 *         remove_instance_variable(:@var)
 *       end
 *     end
 *     d = Dummy.new
 *     d.var      #=> 99
 *     d.remove   #=> 99
 *     d.var      #=> nil
 */
mrb_value
mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
{
  mrb_sym sym;
  mrb_value name;
  khash_t(iv) *h;
  khiter_t k;
  mrb_value val;
  mrb_value Qundef = mrb_undef_value();

  mrb_get_args(mrb, "o", &name);
  sym = mrb_to_id(mrb, name);
  //if (OBJ_FROZEN(obj)) mrb_error_frozen("object");
  //if (!mrb_is_instance_id(id)) {
  //    mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id));
  //}
  switch (mrb_type(self)) {
    case MRB_TT_OBJECT:
    case MRB_TT_CLASS:
    case MRB_TT_MODULE:
      if (!mrb_obj_ptr(self)->iv) break;
      h = mrb_obj_ptr(self)->iv;
      if (!h) break;
      k = kh_get(iv, h, sym);
      if (k != kh_end(h)) {
        val = kh_value(h, k);
        if (!mrb_obj_equal(mrb, val, Qundef)) {
          kh_value(h, k) = Qundef;
          return val;
        }
      }
      break;
    default:
      break;
  }
  mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym));
  return mrb_nil_value();            /* not reached */
}
예제 #22
0
파일: variable.c 프로젝트: koie/mruby
static mrb_value
const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
{
    struct RClass *c = base;
    mrb_value v;
    iv_tbl *t;
    mrb_bool retry = 0;
    mrb_sym cm;

L_RETRY:
    while (c) {
        if (c->iv) {
            t = c->iv;
            if (iv_get(mrb, t, sym, &v))
                return v;
        }
        c = c->super;
    }
    if (!retry && base && base->tt == MRB_TT_MODULE) {
        c = mrb->object_class;
        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_raisef(mrb, E_NAME_ERROR, "uninitialized constant %s",
               mrb_sym2name(mrb, sym));
    /* not reached */
    return mrb_nil_value();
}
예제 #23
0
파일: backtrace.c 프로젝트: okkez/mruby
mrb_value
mrb_restore_backtrace(mrb_state *mrb)
{
  int i;
  mrb_value backtrace;

  backtrace = mrb_ary_new(mrb);
  for (i = 0; i < mrb->backtrace.n; i++) {
    int ai;
    mrb_backtrace_entry *entry;
    mrb_value mrb_entry;
    char buf[32];

    ai = mrb_gc_arena_save(mrb);
    entry = &(mrb->backtrace.entries[i]);

    mrb_entry = mrb_str_new_cstr(mrb, entry->filename);
    snprintf(buf, sizeof(buf), ":%d", entry->lineno);
    mrb_str_cat_cstr(mrb, mrb_entry, buf);
    if (entry->method_id != 0) {
      mrb_str_cat_lit(mrb, mrb_entry, ":in ");

      if (entry->klass) {
        mrb_str_cat_cstr(mrb, mrb_entry, mrb_class_name(mrb, entry->klass));
        mrb_str_cat(mrb, mrb_entry, &entry->sep, 1);
      }

      mrb_str_cat_cstr(mrb, mrb_entry, mrb_sym2name(mrb, entry->method_id));
    }

    mrb_ary_push(mrb, backtrace, mrb_entry);

    mrb_gc_arena_restore(mrb, ai);
  }

  return backtrace;
}
예제 #24
0
파일: struct.c 프로젝트: chancelab/mruby
static mrb_value
mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
{
  mrb_value members, *ptr, *ptr_members;
  mrb_int i, len;

  members = mrb_struct_members(mrb, s);
  len = RARRAY_LEN(members);
  if (RSTRUCT_LEN(s) != len) {
    mrb_raisef(mrb, E_TYPE_ERROR,
               "struct size differs (%" PRIdMRB_INT " required %" PRIdMRB_INT " given)",
               len, RSTRUCT_LEN(s));
  }
  ptr = RSTRUCT_PTR(s);
  ptr_members = RARRAY_PTR(members);
  for (i=0; i<len; i++) {
    if (mrb_symbol(ptr_members[i]) == id) {
      ptr[i] = val;
      return val;
    }
  }
  mrb_raisef(mrb, E_NAME_ERROR, "no member '%s' in struct", mrb_sym2name(mrb, id));
  return val;                   /* not reach */
}
예제 #25
0
파일: struct.c 프로젝트: charliesome/mruby
static mrb_value
mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
{
    mrb_value members, *ptr, *ptr_members;
    long i, len;

    members = mrb_struct_members(mrb, s);
    len = RARRAY_LEN(members);
    mrb_struct_modify(s);
    if (RSTRUCT_LEN(s) != len) {
      mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)",
             len, RSTRUCT_LEN(s));
    }
    ptr = RSTRUCT_PTR(s);
    ptr_members = RARRAY_PTR(members);
    for (i=0; i<len; i++) {
      if (SYM2ID(ptr_members[i]) == id) {
          ptr[i] = val;
          return val;
      }
    }
    mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
    return val; /* not reach */
}
예제 #26
0
파일: dump.c 프로젝트: Zyxwvu/mruby
static uint32_t
get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
{
  uint32_t size = 0;
  int sym_no;

  size += MRB_DUMP_SIZE_OF_LONG; /* slen */
  size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
  size = DUMP_SIZE(size, type);

  for (sym_no = 0; sym_no < irep->slen; sym_no++) {
    const char * name;
    uint16_t nlen =0;

    size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
    if (irep->syms[sym_no] != 0) {
      name = mrb_sym2name(mrb, irep->syms[sym_no]);
      nlen = str_dump_len((char*)name, strlen(name), type);
      size += nlen; /* sn(n) */
    }
  }

  return size;
}
예제 #27
0
파일: kernel.c 프로젝트: Blorgus/mruby
static mrb_value
inspect_obj(mrb_state *mrb, mrb_value obj, mrb_value str, int recur)
{
  if (recur) {
    mrb_str_cat2(mrb, str, " ...");
  }
  else {
    khiter_t k;
    kh_iv_t *h = RCLASS_IV_TBL(obj);

    if (h) {
      for (k = kh_begin(h); k != kh_end(h); k++) {
        if (kh_exist(h, k)){
          mrb_sym id = kh_key(h, k);
          mrb_value value = kh_value(h, k);

          /* need not to show internal data */
          if (RSTRING_PTR(str)[0] == '-') { /* first element */
            RSTRING_PTR(str)[0] = '#';
            mrb_str_cat2(mrb, str, " ");
          }
          else {
            mrb_str_cat2(mrb, str, ", ");
          }
          mrb_str_cat2(mrb, str, mrb_sym2name(mrb, id));
          mrb_str_cat2(mrb, str, "=");
          mrb_str_append(mrb, str, mrb_inspect(mrb, value));
        }
      }
    }
  }
  mrb_str_cat2(mrb, str, ">");
  RSTRING_PTR(str)[0] = '#';

  return str;
}
예제 #28
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
}
예제 #29
0
파일: cdump.c 프로젝트: jshakespear/mruby
int
make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
{
  mrb_irep *irep = mrb->irep[irep_no];
  int n;
  char *buf = 0;
  size_t buf_len, str_len;

  if (irep == 0)
    return -1;

  buf_len = MRB_CDUMP_LINE_LEN;
  if ((buf = mrb_malloc(mrb, buf_len)) == 0 ) {
    return MRB_CDUMP_GENERAL_FAILURE;
  }

  SOURCE_CODE0     ("  ai = mrb->arena_idx;");
  SOURCE_CODE0     ("  irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));");
  SOURCE_CODE0     ("  irep->idx = idx++;");
  SOURCE_CODE      ("  irep->flags = %d | MRB_ISEQ_NOFREE;",                          irep->flags);
  SOURCE_CODE      ("  irep->nlocals = %d;",                                          irep->nlocals);
  SOURCE_CODE      ("  irep->nregs = %d;",                                            irep->nregs);
  SOURCE_CODE      ("  irep->ilen = %d;",                                             irep->ilen);
  SOURCE_CODE      ("  irep->iseq = iseq_%d;",                                        irep_no);

  SOURCE_CODE      ("  irep->slen = %d;",                                             irep->slen);
  if(irep->slen > 0) {
    SOURCE_CODE    ("  irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*%d);",            irep->slen);
    for (n=0; n<irep->slen; n++)
      if (irep->syms[n]) {
        SOURCE_CODE  ("  irep->syms[%d] = mrb_intern(mrb, \"%s\");",                  n, mrb_sym2name(mrb, irep->syms[n]));
      }
  }
  else
    SOURCE_CODE0   ("  irep->syms = NULL;");

  SOURCE_CODE      ("  irep->plen = %d;",                                             irep->plen);
  if(irep->plen > 0) {
    SOURCE_CODE    ("  irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*%d);",          irep->plen);
    for (n=0; n<irep->plen; n++) {
      switch (irep->pool[n].tt) {
      case MRB_TT_FLOAT:
        SOURCE_CODE("  irep->pool[%d] = mrb_float_value(%.16e);",                     n, irep->pool[n].value.f); break;
      case MRB_TT_FIXNUM:
        SOURCE_CODE("  irep->pool[%d] = mrb_fixnum_value(%d);",                       n, irep->pool[n].value.i); break; 
     case MRB_TT_STRING:
        str_len = str_format_len(irep->pool[n]) + 1;
        if ( str_len > buf_len ) {
          buf_len = str_len;
          if ((buf = mrb_realloc(mrb, buf, buf_len)) == 0 ) {
            return MRB_CDUMP_GENERAL_FAILURE;
          }
        }
        memset(buf, 0, buf_len);
        SOURCE_CODE("  irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);",               n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break;
      /* TODO MRB_TT_REGEX */
      default: break;
      }
    }
  }
  else
    SOURCE_CODE0   ("  irep->pool = NULL;");
  SOURCE_CODE0     ("  mrb->irep_len = idx;");
  SOURCE_CODE0     ("  mrb->arena_idx = ai;");
  SOURCE_CODE0("");
  return MRB_CDUMP_OK;
}
예제 #30
0
파일: backtrace.c 프로젝트: kelcecil/mruby
static void
output_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, output_stream_func func, void *stream)
{
  mrb_callinfo *ci;
  const char *filename, *method, *sep;
  int i, lineno, tracehead = 1;

  if (ciidx >= mrb->c->ciend - mrb->c->cibase)
    ciidx = 10; /* ciidx is broken... */

  for (i = ciidx; i >= 0; i--) {
    ci = &mrb->c->cibase[i];
    filename = NULL;
    lineno = -1;

    if (!ci->proc) continue;
    if (MRB_PROC_CFUNC_P(ci->proc)) {
      continue;
    }
    else {
      mrb_irep *irep = ci->proc->body.irep;
      mrb_code *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 = pc0;
      }
      filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
      lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
    }
    if (lineno == -1) continue;
    if (ci->target_class == ci->proc->target_class)
      sep = ".";
    else
      sep = "#";

    if (!filename) {
      filename = "(unknown)";
    }

    if (tracehead) {
      func(mrb, stream, 1, "trace:\n");
      tracehead = 0;
    }
    method = mrb_sym2name(mrb, ci->mid);
    if (method) {
      const char *cn = mrb_class_name(mrb, ci->proc->target_class);

      if (cn) {
        func(mrb, stream, 1, "\t[%d] ", i);
        func(mrb, stream, 0, "%s:%d:in %s%s%s", filename, lineno, cn, sep, method);
        func(mrb, stream, 1, "\n");
      }
      else {
        func(mrb, stream, 1, "\t[%d] ", i);
        func(mrb, stream, 0, "%s:%d:in %s", filename, lineno, method);
        func(mrb, stream, 1, "\n");
      }
    }
    else {
        func(mrb, stream, 1, "\t[%d] ", i);
        func(mrb, stream, 0, "%s:%d", filename, lineno);
        func(mrb, stream, 1, "\n");
    }
  }
}