Exemple #1
0
void
mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
{
  struct RClass *ins_pos;

  ins_pos = c;
  while (m) {
    struct RClass *p = c, *ic;
    int superclass_seen = 0;

    if (c->mt == m->mt) {
      mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
    }
    while (p) {
      if (c != p && p->tt == MRB_TT_CLASS) {
        superclass_seen = 1;
      }
      else if (p->mt == m->mt){
        if (p->tt == MRB_TT_ICLASS && !superclass_seen) {
          ins_pos = p;
        }
        goto skip;
      }
      p = p->super;
    }
    ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class);
    if (m->tt == MRB_TT_ICLASS) {
      ic->c = m->c;
    }
    else {
      ic->c = m;
    }
    ic->mt = m->mt;
    ic->iv = m->iv;
    ic->super = ins_pos->super;
    ins_pos->super = ic;
    mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
    ins_pos = ic;
  skip:
    m = m->super;
  }
}
Exemple #2
0
/*
 *  call-seq:
 *     obj.clone -> an_object
 *
 *  Produces a shallow copy of <i>obj</i>---the instance variables of
 *  <i>obj</i> are copied, but not the objects they reference. Copies
 *  the frozen state of <i>obj</i>. See also the discussion
 *  under <code>Object#dup</code>.
 *
 *     class Klass
 *        attr_accessor :str
 *     end
 *     s1 = Klass.new      #=> #<Klass:0x401b3a38>
 *     s1.str = "Hello"    #=> "Hello"
 *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
 *     s2.str[1,4] = "i"   #=> "i"
 *     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
 *     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
 *
 *  This method may have class-specific behavior.  If so, that
 *  behavior will be documented under the #+initialize_copy+ method of
 *  the class.
 *
 *  Some Class(True False Nil Symbol Fixnum Float) Object  cannot clone.
 */
MRB_API mrb_value
mrb_obj_clone(mrb_state *mrb, mrb_value self)
{
  struct RObject *p;
  mrb_value clone;

  if (mrb_immediate_p(self)) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
  }
  if (mrb_type(self) == MRB_TT_SCLASS) {
    mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
  }
  p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
  p->c = mrb_singleton_class_clone(mrb, self);
  mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
  clone = mrb_obj_value(p);
  init_copy(mrb, clone, self);

  return clone;
}
Exemple #3
0
static void
make_metaclass(mrb_state *mrb, struct RClass *c)
{
  struct RClass *sc;

  if (c->c->tt == MRB_TT_SCLASS) {
    return;
  }
  sc = mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class);
  sc->mt = 0;
  if (!c->super) {
    sc->super = mrb->class_class;
  }
  else {
    sc->super = c->super->c;
  }
  c->c = sc;
  mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)sc);
  mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)sc->super);
}
Exemple #4
0
struct RProc *
mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
{
  struct RProc *p;
  mrb_callinfo *ci = mrb->c->ci;

  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
  p->target_class = 0;
  if (ci) {
    if (ci->proc)
      p->target_class = ci->proc->target_class;
    if (!p->target_class)
      p->target_class = ci->target_class;
  }
  p->body.irep = irep;
  p->env = 0;
  mrb_irep_incref(mrb, irep);

  return p;
}
Exemple #5
0
struct RProc *
mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
{
  struct RProc *p = mrb_proc_new(mrb, irep);
  struct REnv *e;

  if (!mrb->ci->env) {
    e = mrb_obj_alloc(mrb, MRB_TT_ENV, mrb->ci->proc->env);
    e->flags= (unsigned int)irep->nlocals;
    e->mid = mrb->ci->mid;
    e->cioff = mrb->ci - mrb->cibase;
    e->stack = mrb->stack;
    mrb->ci->env = e;
  }
  else {
    e = mrb->ci->env;
  }
  p->env = e;
  return p;
}
Exemple #6
0
mrb_value
mrb_instance_new(mrb_state *mrb, mrb_value cv)
{
  struct RClass *c = mrb_class_ptr(cv);
  struct RObject *o;
  enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
  mrb_value obj, blk;
  mrb_value *argv;
  int argc;

  if (c->tt == MRB_TT_SCLASS)
    mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");

  if (ttype == 0) ttype = MRB_TT_OBJECT;
  o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
  obj = mrb_obj_value(o);
  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
  mrb_funcall_with_block(mrb, obj, mrb->init_sym, argc, argv, blk);

  return obj;
}
Exemple #7
0
static struct RArray*
ary_new_capa(mrb_state *mrb, mrb_int capa)
{
  struct RArray *a;
  mrb_int blen;

  if (capa > ARY_MAX_SIZE) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
  }
  blen = capa * sizeof(mrb_value) ;
  if (blen < capa) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
  }

  a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
  a->ptr = (mrb_value *)mrb_malloc(mrb, blen);
  a->aux.capa = capa;
  a->len = 0;

  return a;
}
Exemple #8
0
/* Soon:

struct RProc *mrbb_closure_new(mrb_state* mrb, mrb_func_t cfunc, unsigned int nlocals)
{
  struct RProc *p = mrb_closure_new_cfunc(mrb, cfunc);

  p->flags |= MRB_PROC_MRBCFUNC;

  return p;
}
*/
struct RProc *mrbb_closure_new(mrb_state* mrb, mrb_func_t cfunc, unsigned int nlocals)
{
  struct RProc *p = mrbb_proc_new(mrb, cfunc);

  // stolen from mrb_closure_new()
  struct REnv *e;

  if (!mrb->ci->env) {
    e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->ci->proc->env);
    e->flags= nlocals;
    e->mid = mrb->ci->mid;
    e->cioff = mrb->ci - mrb->cibase;
    e->stack = mrb->stack;
    mrb->ci->env = e;
  }
  else {
    e = mrb->ci->env;
  }
  p->env = e;

  return p;
}
Exemple #9
0
static mrb_value
mrb_hash_dup(mrb_state *mrb, mrb_value hash)
{
  struct RHash* ret;
  khash_t(ht) *h, *ret_h;
  khiter_t k, ret_k;
  mrb_value ifnone, vret;

  h = RHASH_TBL(hash);
  ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
  ret->ht = kh_init(ht, mrb);

  if (h && kh_size(h) > 0) {
    ret_h = ret->ht;

    for (k = kh_begin(h); k != kh_end(h); k++) {
      if (kh_exist(h, k)) {
        int ai = mrb_gc_arena_save(mrb);
        ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
        mrb_gc_arena_restore(mrb, ai);
        kh_val(ret_h, ret_k).v = kh_val(h, k).v;
        kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;
      }
    }
  }

  if (MRB_RHASH_DEFAULT_P(hash)) {
    ret->flags |= MRB_HASH_DEFAULT;
  }
  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
    ret->flags |= MRB_HASH_PROC_DEFAULT;
  }
  vret = mrb_obj_value(ret);
  ifnone = RHASH_IFNONE(hash);
  if (!mrb_nil_p(ifnone)) {
      mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
  }
  return vret;
}
Exemple #10
0
/*
 * 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");
  }
  if (mrb_type(blk) != MRB_TT_PROC) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
  }
  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);
    mrb_proc_copy(p2, p);
    p2->flags |= MRB_PROC_STRICT;
    return mrb_obj_value(p2);
  }
  return blk;
}
Exemple #11
0
static mrb_value
read_string_value(MarshalContext *ctx)
{
	mrb_state *mrb = ctx->mrb;
	int len = read_fixnum(ctx);

	struct RString *str =
		(struct RString*) mrb_obj_alloc
			(mrb, MRB_TT_STRING, mrb->string_class);

	str->c = mrb->string_class;
	str->len = len;
	str->aux.capa = len;
	str->ptr = (char*) mrb_malloc(mrb, len+1);

	ctx->readData(str->ptr, len);
	str->ptr[len] = '\0';

	mrb_value str_obj = mrb_obj_value(str);

	return str_obj;
}
Exemple #12
0
struct RProc *
mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t f, mrb_int argc, const mrb_value *argv)
{
    struct RProc *p;
    struct REnv *e;
    int ai, i;

    p = mrb_proc_new_cfunc(mrb, f);
    ai = mrb_gc_arena_save(mrb);
    e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
    p->env = e;
    mrb_gc_arena_restore(mrb, ai);

    MRB_ENV_UNSHARE_STACK(e);
    MRB_ENV_STACK_LEN(e) = argc;
    e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
    for (i = 0; i < argc; ++i) {
        e->stack[i] = argv[i];
    }

    return p;
}
Exemple #13
0
struct RClass*
mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
{
  struct RClass *klass = RBASIC(obj)->c;

  //if (!FL_TEST(klass, FL_SINGLETON))
      //return klass;
  if (klass->tt != MRB_TT_SCLASS)
    return klass;
  else {
      //struct clone_method_data data;
      /* copy singleton(unnamed) class */
      //VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
    struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
    //clone->super = objklass->super;

      if ((mrb_type(obj) == MRB_TT_CLASS) ||
          (mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */
          clone->c = clone;
      }
      else {
          clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
      }

      clone->super = klass->super;
      if (klass->iv) {
          clone->iv = klass->iv;
      }
      if (klass->mt) {
          clone->mt = kh_copy(mt, mrb, klass->mt);
      }
      else {
          clone->mt = kh_init(mt, mrb);
      }
      clone->tt = MRB_TT_SCLASS;
      return clone;
  }
}
Exemple #14
0
static struct RArray*
ary_new_capa(mrb_state *mrb, mrb_int capa)
{
  struct RArray *a;
  size_t blen;

  if (capa > ARY_MAX_SIZE) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
  }
  blen = capa * sizeof(mrb_value);

  a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
  if (capa <= MRB_ARY_EMBED_LEN_MAX) {
    ARY_SET_EMBED_LEN(a, 0);
  }
  else {
    a->as.heap.ptr = (mrb_value *)mrb_malloc(mrb, blen);
    a->as.heap.aux.capa = capa;
    a->as.heap.len = 0;
  }

  return a;
}
Exemple #15
0
MRB_API mrb_value mrb_sample_buffer_slice(mrb_state *mrb, mrb_value sample_buffer, mrb_int len, mrb_int offset)
{
  mrb_value buf;
  mrb_sample_buffer *b = 0, *other = 0;

  if (len <= 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "Length must be positive");
  if (offset < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "Offset can not be negative");

  other = mrb_sample_buffer_check(mrb, sample_buffer);

  if (len > other->len - offset) mrb_raise(mrb, E_ARGUMENT_ERROR, "Slice must be completely inside the buffer");

  buf = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_DATA, mrb_class_get(mrb, "SampleBuffer")));

  b = mrb_sample_buffer_alloc(mrb);
  b->shared = other->shared;
  mrb_shared_sample_buffer_ref(mrb, other->shared);
  b->len = len;
  b->offset = offset;
  mrb_data_init(buf, b, &mrb_sample_buffer_type);

  return buf;
}
Exemple #16
0
MRB_API mrb_value mrb_sample_buffer_new_zero(mrb_state *mrb, mrb_int len, mrb_int offset)
{
  mrb_value buf;
  mrb_sample_buffer *b = 0;
  mrb_int i;

  if (len <= 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "Length must be positive");
  if (offset < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "Offset can not be negative");

  buf = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_DATA, mrb_class_get(mrb, "SampleBuffer")));

  b = mrb_sample_buffer_alloc(mrb);
  b->shared = mrb_shared_sample_buffer_alloc(mrb, len);
  b->shared->offset = offset;
  b->len = len;
  b->offset = 0;
  for (i = 0; i < len; ++i) {
    b->shared->buffer[i] = 0;
  }
  mrb_data_init(buf, b, &mrb_sample_buffer_type);

  return buf;
}
Exemple #17
0
mrb_value
mrb_hash_dup(mrb_state *mrb, mrb_value hash)
{
  struct RHash* ret;
  khash_t(ht) *h, *ret_h;
  khiter_t k, ret_k;

  h = RHASH_TBL(hash);
  ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
  ret->ht = kh_init(ht, mrb);

  if (kh_size(h) > 0) {
    ret_h = ret->ht;

    for (k = kh_begin(h); k != kh_end(h); k++) {
      if (kh_exist(h,k)) {
        ret_k = kh_put(ht, ret_h, KEY(kh_key(h,k)));
        kh_val(ret_h, ret_k) = kh_val(h,k);
      }
    }
  }

  return mrb_obj_value(ret);
}
Exemple #18
0
int load_irep(struct VM *vm, char **pos)
{
  char *p = *pos;
  int i;

  p += 4;
  int sz = get_int_4(p);  p += 4;

  if( !check_str_4(p, "0000") ){
    return LOAD_FILE_IREP_ERROR_VERSION;
  }
  p += 4;

  int cnt = 0;
  while( cnt < sz ){
    int sz2 = get_int_4(p);  p += 4;

    // new irep
    mrb_irep *irep = new_irep();
    if( irep == 0 ){
      return LOAD_FILE_IREP_ERROR_ALLOCATION;
    }

    // add irep into vm->irep (at tail)
    // TODO: Optimize this process
    if( vm->irep == 0 ){
      vm->irep = irep;
    } else {
      mrb_irep *p = vm->irep;
      while( p->next != 0 ){
        p = p->next;
      }
      p->next = irep;
    }
    irep->next = 0;

    // nlocals,nregs,rlen
    irep->nlocals = get_int_2(p);  p += 2;
    irep->nregs = get_int_2(p);    p += 2;
    irep->rlen = get_int_2(p);     p += 2;
    irep->ilen = get_int_4(p);     p += 4;

    // padding (align=4 ?)
    p = (char *)( ( (unsigned long)p + 3 ) & ~3L );

    // code
    irep->code = (uint8_t *)p;
    p += irep->ilen * 4;

    // pool
    irep->ptr_to_pool = 0;
    int plen = get_int_4(p);    p += 4;
    for( i=0 ; i<plen ; i++ ){
      int tt = (int)*p++;
      int obj_size = get_int_2(p);   p += 2;
      mrb_object *ptr = mrb_obj_alloc(MRB_TT_FALSE);
      if( ptr == 0 ){
        return LOAD_FILE_IREP_ERROR_ALLOCATION;
      }
      switch( tt ){
#if MRUBYC_USE_FLOAT
        case 2: { // IREP_TT_FLOAT
          char buf[obj_size+1];
          memcpy(buf, p, obj_size);
          buf[obj_size] = '\0';
          sscanf(buf, "%lf", &ptr->value.d);
          ptr->tt = MRB_TT_FLOAT;
        } break;
#endif
        default:
          break;
      }
      if( irep->ptr_to_pool == 0 ){
        irep->ptr_to_pool = ptr;
      } else {
        mrb_object *pp = irep->ptr_to_pool;
        while( pp->next != 0 ) pp = pp->next;
        pp->next = ptr;
      }
      p += obj_size;
    }

    //  syms
    irep->ptr_to_sym = (uint8_t*)p;
    int slen = get_int_4(p);    p += 4;
    for( i=0 ; i<slen ; i++ ){
      int s = get_int_2(p);     p += 2;
      p += s+1;
    }

    // cnt
    cnt += sz2 + 8;
  }

  /* TODO: size */
  *pos += sz;
  return NO_ERROR;
}
Exemple #19
0
static struct RProc*
create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)
{
  mrbc_context *cxt;
  struct mrb_parser_state *p;
  struct RProc *proc;
  struct REnv *e;
  struct mrb_context *c = mrb->c;

  if (!mrb_nil_p(binding)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
  }

  cxt = mrbc_context_new(mrb);
  cxt->lineno = line;

  if (!file) {
    file = "(eval)";
  }
  mrbc_filename(mrb, cxt, file);
  cxt->capture_errors = TRUE;
  cxt->no_optimize = TRUE;

  p = mrb_parse_nstring(mrb, s, len, cxt);

  /* only occur when memory ran out */
  if (!p) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state.");
  }

  if (0 < p->nerr) {
    /* parse error */
    char buf[256];
    int n;
    n = snprintf(buf, sizeof(buf), "line %d: %s\n", p->error_buffer[0].lineno, p->error_buffer[0].message);
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_exc_raise(mrb, mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
  }

  proc = mrb_generate_code(mrb, p);
  if (proc == NULL) {
    /* codegen error */
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
  }
  if (c->ci[-1].proc->target_class) {
    proc->target_class = c->ci[-1].proc->target_class;
  }
  e = c->ci[-1].proc->env;
  if (!e) e = c->ci[-1].env;
  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e);
  e->mid = c->ci[-1].mid;
  e->cioff = c->ci - c->cibase - 1;
  e->stack = c->ci->stackent;
  MRB_SET_ENV_STACK_LEN(e, c->ci[-1].proc->body.irep->nlocals);
  c->ci->env = e;
  proc->env = e;
  patch_irep(mrb, proc->body.irep, 0);

  mrb_parser_free(p);
  mrbc_context_free(mrb, cxt);

  return proc;
}
Exemple #20
0
static struct RProc*
create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
{
  mrbc_context *cxt;
  struct mrb_parser_state *p;
  struct RProc *proc;
  struct REnv *e;
  mrb_callinfo *ci = &mrb->c->ci[-1]; /* callinfo of eval caller */
  struct RClass *target_class = NULL;
  int bidx;

  if (!mrb_nil_p(binding)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
  }

  cxt = mrbc_context_new(mrb);
  cxt->lineno = (short)line;

  mrbc_filename(mrb, cxt, file ? file : "(eval)");
  cxt->capture_errors = TRUE;
  cxt->no_optimize = TRUE;

  p = mrb_parse_nstring(mrb, s, len, cxt);

  /* only occur when memory ran out */
  if (!p) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state.");
  }

  if (0 < p->nerr) {
    /* parse error */
    mrb_value str;

    if (file) {
      str = mrb_format(mrb, " file %S line %S: %S",
                       mrb_str_new_cstr(mrb, file),
                       mrb_fixnum_value(p->error_buffer[0].lineno),
                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
    }
    else {
      str = mrb_format(mrb, " line %S: %S",
                       mrb_fixnum_value(p->error_buffer[0].lineno),
                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
    }
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str));
  }

  proc = mrb_generate_code(mrb, p);
  if (proc == NULL) {
    /* codegen error */
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
  }
  target_class = MRB_PROC_TARGET_CLASS(ci->proc);
  if (!MRB_PROC_CFUNC_P(ci->proc)) {
    if (ci->env) {
      e = ci->env;
    }
    else {
      e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV,
                                      (struct RClass*)target_class);
      e->mid = ci->mid;
      e->stack = ci[1].stackent;
      e->cxt = mrb->c;
      MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
      bidx = ci->argc;
      if (ci->argc < 0) bidx = 2;
      else bidx += 1;
      MRB_ENV_SET_BIDX(e, bidx);
      ci->env = e;
    }
    proc->e.env = e;
    proc->flags |= MRB_PROC_ENVSET;
    mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e);
  }
  proc->upper = ci->proc;
  mrb->c->ci->target_class = target_class;
  patch_irep(mrb, proc->body.irep, 0, proc->body.irep);
  /* mrb_codedump_all(mrb, proc); */

  mrb_parser_free(p);
  mrbc_context_free(mrb, cxt);

  return proc;
}
Exemple #21
0
static struct RObject *
method_object_alloc(mrb_state *mrb, struct RClass *mclass)
{
  return (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mclass);
}
Exemple #22
0
// based on https://gist.github.com/3066997
static mrb_value
migrate_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2) {
  mrb_value nv;

  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
  case MRB_TT_EXCEPTION:
    {
      struct RObject *o = mrb_obj_ptr(v);
      mrb_value path = mrb_class_path(mrb, o->c);
      struct RClass *c;

      if (mrb_nil_p(path)) {
        mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate class");
      }
      c = mrb_class_get(mrb2, RSTRING_PTR(path));
      nv = mrb_obj_value(mrb_obj_alloc(mrb2, mrb_type(v), c));
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
    nv = v;
    break;
  case MRB_TT_SYMBOL:
    nv = mrb_symbol_value(migrate_sym(mrb, mrb_symbol(v), mrb2));
    break;
  case MRB_TT_FLOAT:
    nv = mrb_float_value(mrb2, mrb_float(v));
    break;
  case MRB_TT_STRING:
    nv = mrb_str_new(mrb2, RSTRING_PTR(v), RSTRING_LEN(v));
    break;
  case MRB_TT_RANGE:
    {
      struct RRange *r = mrb_range_ptr(v);
      nv = mrb_range_new(mrb2,
                         migrate_simple_value(mrb, r->edges->beg, mrb2),
                         migrate_simple_value(mrb, r->edges->end, mrb2),
                         r->excl);
    }
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0, *a1;
      int i;

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a0->len);
      a1 = mrb_ary_ptr(nv);
      for (i=0; i<a0->len; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        a1->ptr[i] = migrate_simple_value(mrb, a0->ptr[i], mrb2);
        a1->len++;
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;

      nv = mrb_hash_new(mrb2);
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        mrb_value k = migrate_simple_value(mrb, mrb_ary_entry(ka, i), mrb2);
        mrb_value o = migrate_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2);
        mrb_hash_set(mrb2, nv, k, o);
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_DATA:
    if (!is_safe_migratable_datatype(DATA_TYPE(v)))
      mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    nv = v;
    DATA_PTR(nv) = DATA_PTR(v);
    DATA_TYPE(nv) = DATA_TYPE(v);
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  default:
    mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    break;
  }
  return nv;
}