Пример #1
0
AccessClass::AccessClass(RubyValue className, RubyValue methodInfos, RubyValue signalInfos, RubyValue propertyInfos)
{
    setClassName(className.to<QByteArray>());
    protect([&] {
        rb_check_array_type(methodInfos);
        rb_check_array_type(signalInfos);
        rb_check_array_type(propertyInfos);
    });
    for (int i = 0; i < RARRAY_LEN(VALUE(methodInfos)); ++i) {
        RubyValue info = RARRAY_AREF(VALUE(methodInfos), i);
        auto nameSym = info.send("name");
        addMethod(nameSym.to<QByteArray>(),
                  nameSym.toID(),
                  info.send("params").to<QList<QByteArray>>());
    }
    for (int i = 0; i < RARRAY_LEN(VALUE(signalInfos)); ++i) {
        RubyValue info = RARRAY_AREF(VALUE(signalInfos), i);
        auto nameSym = info.send("name");
        addSignal(nameSym.to<QByteArray>(),
                  nameSym.toID(),
                  info.send("params").to<QList<QByteArray>>());
    }
    for (int i = 0; i < RARRAY_LEN(VALUE(propertyInfos)); ++i) {
        RubyValue info = RARRAY_AREF(VALUE(propertyInfos), i);
        addProperty(info.send("name").to<QByteArray>(),
                    info.send("getter").toID(),
                    info.send("setter").toID(),
                    Property::Flag::Readable | Property::Flag::Writable,
                    true,
                    info.send("notifier").toID());
    }
}
Пример #2
0
static VALUE
rhash_create(VALUE klass, SEL sel, int argc, VALUE *argv)
{
    if (argc == 1) {
	VALUE tmp = rhash_try_convert(Qnil, 0, argv[0]);
	if (!NIL_P(tmp)) {
	    VALUE hash = rhash_alloc(klass, 0);
	    if (IS_RHASH(tmp)) {
		GC_WB(&RHASH(hash)->tbl, st_copy(RHASH(tmp)->tbl));
	    }
	    else {
		VALUE keys = rb_hash_keys(tmp);
		for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) {
		    VALUE key = RARRAY_AT(keys, i);
		    VALUE val = rb_hash_lookup(tmp, key);
		    rhash_aset(hash, 0, key, val);  
		}
	    }
	    return hash;
	}

	tmp = rb_check_array_type(argv[0]);
	if (!NIL_P(tmp)) {
	    VALUE hash = rhash_alloc(klass, 0);
	    for (int i = 0; i < RARRAY_LEN(tmp); ++i) {
		VALUE v = rb_check_array_type(RARRAY_AT(tmp, i));
		if (NIL_P(v)) {
		    continue;
		}
		const long len = RARRAY_LEN(v);
		if (len < 1 || 2 < len) {
		    continue;
		}
		rhash_aset(hash, 0, RARRAY_AT(v, 0), RARRAY_AT(v, 1));
	    }
	    return hash;
	}
    }
    if (argc % 2 != 0) {
	rb_raise(rb_eArgError, "odd number of arguments for Hash");
    }

    VALUE hash = rhash_alloc(klass, 0);
    for (int i = 0; i < argc; i += 2) {
        rb_hash_aset(hash, argv[i], argv[i + 1]);
    }

    return hash;
}
Пример #3
0
/** Takes a Ruby array of Ruby Symbols and computes the C
 * alpm_siglevel_t from it. Raises an exception if `ary'
 * doesn’t respond to #to_ary. */
alpm_siglevel_t siglevel_from_ruby(VALUE ary)
{
  alpm_siglevel_t level = 0;

  if (!(RTEST(ary = rb_check_array_type(ary)))) { /*  Single = intended */
    VALUE str = rb_inspect(level);
    rb_raise(rb_eTypeError, "Not an array (#to_ary): %s", StringValuePtr(str));
    return Qnil;
  }

  if (rb_ary_includes(ary, STR2SYM("package")))
    level |= ALPM_SIG_PACKAGE;
  if (rb_ary_includes(ary, STR2SYM("package_optional")))
    level |= ALPM_SIG_PACKAGE_OPTIONAL;
  if (rb_ary_includes(ary, STR2SYM("package_marginal_ok")))
    level |= ALPM_SIG_PACKAGE_MARGINAL_OK;
  if (rb_ary_includes(ary, STR2SYM("package_unknown_ok")))
    level |= ALPM_SIG_PACKAGE_UNKNOWN_OK;
  if (rb_ary_includes(ary, STR2SYM("database")))
    level |= ALPM_SIG_DATABASE;
  if (rb_ary_includes(ary, STR2SYM("database_optional")))
    level |= ALPM_SIG_DATABASE_OPTIONAL;
  if (rb_ary_includes(ary, STR2SYM("database_marginal_ok")))
    level |= ALPM_SIG_DATABASE_MARGINAL_OK;
  if (rb_ary_includes(ary, STR2SYM("database_unknown_ok")))
    level |= ALPM_SIG_DATABASE_UNKNOWN_OK;
  if (rb_ary_includes(ary, STR2SYM("package_set")))
    level |= ALPM_SIG_PACKAGE_SET;
  if (rb_ary_includes(ary, STR2SYM("package_trust_set")))
    level |= ALPM_SIG_PACKAGE_TRUST_SET;
  if (rb_ary_includes(ary, STR2SYM("use_default")))
    level |= ALPM_SIG_USE_DEFAULT;

  return level;
}
Пример #4
0
static VALUE
lazy_zip(int argc, VALUE *argv, VALUE obj)
{
    VALUE ary, v;
    long i;
    rb_block_call_func *func = lazy_zip_arrays_func;

    if (rb_block_given_p()) {
	return rb_call_super(argc, argv);
    }

    ary = rb_ary_new2(argc);
    for (i = 0; i < argc; i++) {
	v = rb_check_array_type(argv[i]);
	if (NIL_P(v)) {
	    for (; i < argc; i++) {
		if (!rb_respond_to(argv[i], id_each)) {
		    rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
			rb_obj_classname(argv[i]));
		}
	    }
	    ary = rb_ary_new4(argc, argv);
	    func = lazy_zip_func;
	    break;
	}
	rb_ary_push(ary, v);
    }

    return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
					 func, ary),
			   ary, lazy_receiver_size);
}
Пример #5
0
/** call-seq:  time = time

Set the timestamp as removal condition.
Parameters:
[time]   an integer, for specifying ticks, or a tuple of splat of seconds and nanoseconds

Normally used with the flags +SND_SEQ_REMOVE_TIME_AFTER+ or +SND_SEQ_REMOVE_TIME_BEFORE+.

See RRTS::Driver::AlsaRemoveClass_i#condition=.

*/
static VALUE
wrap_snd_seq_remove_events_set_time(int argc, VALUE *argv, VALUE v_rmp)
{
  snd_seq_remove_events_t *rmp;
  Data_Get_Struct(v_rmp, snd_seq_remove_events_t, rmp);
  VALUE v_sec, v_nsec;
  rb_scan_args(argc, argv, "11", &v_sec, &v_nsec);
  snd_seq_timestamp_t time;
  if (NIL_P(v_nsec))
    {
      if (FIXNUM_P(v_sec))
          time.tick = NUM2UINT(v_sec);
      else
        {
          v_sec = rb_check_array_type(v_sec);
          if (!RTEST(v_sec)) RAISE_MIDI_ERROR_FMT0("API call error: bad time format");
          time.time.tv_sec = NUM2UINT(rb_ary_entry(v_sec, 0));
          time.time.tv_nsec = NUM2UINT(rb_ary_entry(v_sec, 1));
        }
    }
  else
    {
      time.time.tv_sec = NUM2UINT(v_sec);
      time.time.tv_nsec = NUM2UINT(v_nsec);
    }
  snd_seq_remove_events_set_time(rmp, &time);
  return Qnil;
}
Пример #6
0
VALUE RObj_to_ruby(VALUE self, VALUE args){

  int conv;
  VALUE obj;
  SEXP robj;

  args = rb_check_array_type(args);

  if (RARRAY_LEN(args) > 1){
    rb_raise(rb_eArgError,"Too many arguments in to_ruby\n");
  }

  if (RARRAY_LEN(args) == 0){
    conv = NUM2INT(rb_iv_get(RSRUBY,"@default_mode"));
  } else {
    conv = NUM2INT(rb_ary_entry(args,0));
  }

  if (conv <= -2 || conv > TOP_MODE) {
    rb_raise(rb_eArgError, "Wrong mode\n");
    return Qnil;
  }

  if (conv < 0)
    conv = TOP_MODE;

  Data_Get_Struct(self, struct SEXPREC, robj);

  obj = to_ruby_with_mode(robj, conv);
  return obj;

}
Пример #7
0
VALUE
rb_yield_splat(VALUE values)
{
    VALUE tmp = rb_check_array_type(values);
    if (NIL_P(tmp)) {
        rb_raise(rb_eArgError, "not an array");
    }
    return rb_vm_yield(RARRAY_LENINT(tmp), RARRAY_PTR(tmp));
}
Пример #8
0
VALUE
rb_yield_splat(VALUE values)
{
    VALUE tmp = rb_check_array_type(values);
    volatile VALUE v;
    if (NIL_P(tmp)) {
        rb_raise(rb_eArgError, "not an array");
    }
    v = rb_yield_0(RARRAY_LEN(tmp), RARRAY_PTR(tmp));
    return v;
}
Пример #9
0
/* Convert a sequence of (name, value) pairs to arguments to an R
   function call */
int
make_argl(VALUE args, SEXP *e)
{
  SEXP rvalue;
  int i;
  VALUE pair, name, value;

  //Ensure we have an array
  args = rb_check_array_type(args);
  
  for (i=0; i<RARRAY_LEN(args); i++) {
    pair = rb_ary_entry(args, i);
    pair = rb_check_array_type(pair);
    if(RARRAY_LEN(pair) != 2)
      rb_raise(rb_eArgError,"Misformed argument in lcall\n");

    /* Name must be a string. If it is empty string '' then no name*/
    name = rb_ary_entry(pair, 0);
    name = StringValue(name);
    name = rb_funcall(rb_const_get(rb_cObject, 
				   rb_intern("RSRuby")),
		      rb_intern("convert_method_name"),1,name);

    /* Value can be anything. */
    value  = rb_ary_entry(pair, 1);
    rvalue = ruby_to_R(value);

    /* Add parameter value to call */
    SETCAR(*e, rvalue);

    /* Add name (if present) */
    if (RSTRING_LEN(name) > 0) 
      {
        SET_TAG(*e, Rf_install(RSTRING_PTR(name)));
      }

    /* Move index to new end of call */
    *e = CDR(*e);
  }
  return 1;
}
Пример #10
0
void _mp4v2_write_chapters(MP4V2Handles *handle) {
  VALUE self = handle->self;
  MP4FileHandle mp4v2 = handle->file;
  VALUE chapters = rb_check_array_type(GET(chapters)), chapter, title;
  double last_stamp = 0, stamp;
  MP4Chapter_t *chaps;
  uint32_t count = 0;

  switch(TYPE(chapters)) {
    case T_ARRAY:
      RARRAY_ALL_INSTANCE(chapters, rb_cChapter, chapter);

      // Make chapters go in order of timestamp
      rb_ary_sort_bang(chapters);

      count = RARRAY_LEN(chapters);
      chaps = handle->chapters = (MP4Chapter_t *)malloc(sizeof(MP4Chapter_t) * count);
      if (!chaps) {
        rb_raise(rb_eNoMemError, "unable to save all changes to file");
      }

      for (uint32_t i = 0; i < count; i++) {
        // Calculate the duration of chapter from previous timestamp and current
        chapter = rb_ary_entry(chapters, i);
        stamp = NUM2DBL(rb_funcall(rb_ivar_get(chapter, rb_intern("@timestamp")), rb_intern("milliseconds"), 0));
        chaps[i].duration = stamp - last_stamp;
        last_stamp = stamp;

        // Get the title of the chapter
        title = rb_encode_utf8(rb_ivar_get(chapter, rb_intern("@title")));
        if (RSTRING_LEN(title) > MP4V2_CHAPTER_TITLE_MAX) {
          rb_raise(rb_eStandardError, "chapter title '%s' is too long, it should be at most %d bytes", RSTRING_PTR(title), MP4V2_CHAPTER_TITLE_MAX);
        }

        memcpy(chaps[i].title, RSTRING_PTR(title), RSTRING_LEN(title)+1);
      }

      if (count > 0) {
        MP4SetChapters(mp4v2, chaps, count, MP4ChapterTypeAny);
      } else {
        MP4DeleteChapters(mp4v2, MP4ChapterTypeAny);
      }

      free(chaps);
      handle->chapters = NULL;
      break;
    case T_NIL:
      MP4DeleteChapters(mp4v2, MP4ChapterTypeAny);
      break;
    default:;
  }
}
Пример #11
0
/*
 * Returns the #dirname and the #basename in an Array.
 *
 * See File.split.
 */
static VALUE
path_split(VALUE self)
{
    VALUE str = get_strpath(self);
    VALUE ary, dirname, basename;
    ary = rb_funcall(rb_cFile, rb_intern("split"), 1, str);
    ary = rb_check_array_type(ary);
    dirname = rb_ary_entry(ary, 0);
    basename = rb_ary_entry(ary, 1);
    dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self));
    basename = rb_class_new_instance(1, &basename, rb_obj_class(self));
    return rb_ary_new3(2, dirname, basename);
}
Пример #12
0
static inline int
args_check_block_arg0(struct args_info *args, rb_thread_t *th)
{
    VALUE ary = Qnil;

    if (args->rest && RARRAY_LEN(args->rest) == 1) {
	VALUE arg0 = RARRAY_AREF(args->rest, 0);
	ary = rb_check_array_type(arg0);
    }
    else if (args->argc == 1) {
	VALUE arg0 = args->argv[0];
	ary = rb_check_array_type(arg0);
	args->argv[0] = arg0; /* see: https://bugs.ruby-lang.org/issues/8484 */
    }

    if (!NIL_P(ary)) {
	args->rest = ary;
	args->rest_index = 0;
	args->argc = 0;
	return TRUE;
    }

    return FALSE;
}
Пример #13
0
static VALUE
lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
{
    VALUE ary = rb_check_array_type(obj);
    if (NIL_P(ary)) {
	rb_funcall(yielder, id_yield, 1, obj);
    }
    else {
	long i;
	for (i = 0; i < RARRAY_LEN(ary); i++) {
	    rb_funcall(yielder, id_yield, 1, RARRAY_AREF(ary, i));
	}
    }
    return Qnil;
}
Пример #14
0
static VALUE
lazy_flat_map_to_ary(VALUE obj)
{
    NODE *memo = RNODE(obj);
    VALUE ary = rb_check_array_type(memo->u1.value);
    if (NIL_P(ary)) {
	rb_funcall(memo->u2.value, id_yield, 1, memo->u1.value);
    }
    else {
	long i;
	for (i = 0; i < RARRAY_LEN(ary); i++) {
	    rb_funcall(memo->u2.value, id_yield, 1, RARRAY_PTR(ary)[i]);
	}
    }
    return Qnil;
}
Пример #15
0
VALUE RObj_lcall(VALUE self, VALUE args){
  SEXP  exp, e, res;
  SEXP  r_obj;
  int conv, default_mode;
  VALUE obj;

  //Ensure we have an array
  args = rb_check_array_type(args);

  // A SEXP with the function to call and the arguments
  PROTECT(exp = allocVector(LANGSXP, RARRAY_LEN(args)+1));
  e = exp;

  Data_Get_Struct(self, struct SEXPREC, r_obj);

  SETCAR(e, r_obj);
  e = CDR(e);

  // Add the arguments to the SEXP
  if (!make_argl(args, &e)) {
    UNPROTECT(1);
    return Qnil;
  }

  // Evaluate
  PROTECT(res = do_eval_expr(exp));
  if (!res) {
    UNPROTECT(2);
    return Qnil;
  }

  default_mode = NUM2INT(rb_iv_get(RSRUBY,"@default_mode"));

  // Convert
  if (default_mode < 0){
    conv = NUM2INT(rb_iv_get(self,"@conversion"));
  } else {
    conv = default_mode;
  }

  obj = to_ruby_with_mode(res, conv);

  UNPROTECT(2);

  return obj;
}
Пример #16
0
GimpParam *
rb2GimpParams (VALUE rbparams,
               gint  *count)
{
  rbparams = rb_check_array_type(rbparams);
  int num = RARRAY_LEN(RARRAY(rbparams));
  VALUE *arr = RARRAY_PTR(RARRAY(rbparams));

  GimpParam *params = g_new(GimpParam, num);

  int i;
  for (i=0; i<num; i++)
    params[i] = rb2GimpParam(arr[i]);

  *count = (gint)num;
  return params;
}
Пример #17
0
Carr * r2carr(VALUE value) {
  Carr *M = NULL;
  int rows = RARRAY_LEN(value);
  if (rows > 0) {
    VALUE colzero = rb_ary_entry(value, 0);
    colzero = rb_check_array_type(colzero);
    if (!NIL_P(colzero)) {
      rb_raise(rb_eTypeError, "Matrix two dimensional instead of one");
    }
    M = carr_new(rows);
     int i;
     for (i=0;i<rows;++i) {
       VALUE val = rb_ary_entry(value, i);
       M->data[i] = NUM2DBL(val);
     }
  }
  return M;
}
Пример #18
0
/** call-seq: time_real = sec, nsec

For removing events based on this specified realtime. It is also possible to pass a tuple
as single argument.

See RRTS::Driver::AlsaRemoveClass_i#condition=.
*/
static VALUE
ARE_set_time_real(int argc, VALUE *argv, VALUE v_rmp)
{
  snd_seq_remove_events_t *rmp;
  Data_Get_Struct(v_rmp, snd_seq_remove_events_t, rmp);
  VALUE v_sec, v_nsec;
  rb_scan_args(argc, argv, "11", &v_sec, &v_nsec);
  if (NIL_P(v_nsec))
  {
    v_sec = rb_check_array_type(v_sec);
    if (!RTEST(v_sec)) RAISE_MIDI_ERROR_FMT0("API call error: realtime needs sec+nsec tuple");
    v_nsec = rb_ary_entry(v_sec, 1);
    v_sec = rb_ary_entry(v_sec, 0);
  }
  snd_seq_timestamp_t time;
  time.time.tv_sec = NUM2UINT(v_sec);
  time.time.tv_nsec = NUM2UINT(v_nsec);
  snd_seq_remove_events_set_time(rmp, &time);
  return Qnil;
}
Пример #19
0
int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){

  VALUE vertex;
  VALUE tmp;
  VALUE i;

  tmp = rb_check_array_type(va);

  if(NIL_P(tmp))
    rb_raise(cIGraphError, "Array expected\n");
    
  //Initialize edge vector
  //igraph_vector_init_int(nv,0);
  for (i=0; i<RARRAY_LEN(va); i++) {
    vertex = RARRAY_PTR(va)[i];
    igraph_vector_push_back(nv,cIGraph_get_vertex_id(graph, vertex));
  }

  return 0;

}
Пример #20
0
// Wrappers for matrix class
Cmat * r2cmat(VALUE value) {
  Cmat *M = NULL;
  int rows = RARRAY_LEN(value);
  int cols = 0;
  if (rows > 0) {
    VALUE colzero = rb_ary_entry(value, 0);
    colzero = rb_check_array_type(colzero);
    if (NIL_P(colzero)) {
      rb_raise(rb_eTypeError, "Matrix one dimensional instead of two");
    }
    cols = RARRAY_LEN(colzero);
    M = cmat_new(rows,cols);
     int i,j;
     for (i=0;i<rows;++i) {
       VALUE col = rb_ary_entry(value, i);
         for (j=0;j<cols;++j) {
           M->data[i][j] = NUM2DBL(rb_ary_entry(col, j));
         }
     }
  }
  return M;
}
Пример #21
0
/**
 * call-seq:
 *   servers=( ary )
 *
 * Replace the list of servers for this database with the
 * given one.
 *
 * === Parameters
 * [servers]
 *   An array of URLs.
 */
static VALUE set_servers(VALUE self, VALUE ary)
{
  alpm_db_t* p_db = NULL;
  alpm_list_t* servers = NULL;
  int i;
  Data_Get_Struct(self, alpm_db_t, p_db);

  if (!RTEST(ary = rb_check_array_type(ary))) { /* Single = intended */
    rb_raise(rb_eTypeError, "Argument is no array (#to_ary)");
      return Qnil;
  }

  for(i=0; i < RARRAY_LEN(ary); i++) {
    VALUE url = rb_ary_entry(ary, i);
    servers = alpm_list_add(servers, StringValuePtr(url));
  }

  alpm_db_set_servers(p_db, servers);
  alpm_list_free(servers);

  return ary;
}
Пример #22
0
static gpointer
rb2gimp_array (GimpPDBArgType type,
               VALUE          rbarr)
{
  rbarr = rb_check_array_type(rbarr);
  int count = RARRAY_LEN(RARRAY(rbarr));
  VALUE *arr = RARRAY_PTR(RARRAY(rbarr));

  int i;
  gint32  *int32arr;
  gint16  *int16arr;
  gdouble *floatarr;
  gchar  **stringarr;

  switch (type)
    {
    case GIMP_PDB_INT32ARRAY:
      int32arr = g_new(gint32, count);
      for(i=0; i<count; i++) int32arr[i] = (gint32)NUM2INT(arr[i]);
      return int32arr;

    case GIMP_PDB_INT16ARRAY:
      int16arr = g_new(gint16, count);
      for(i=0; i<count; i++) int16arr[i] = (gint16)NUM2INT(arr[i]);
      return int16arr;

    case GIMP_PDB_FLOATARRAY:
      floatarr = g_new(gdouble, count);
      for(i=0; i<count; i++) floatarr[i] = (gdouble)NUM2DBL(arr[i]);
      return floatarr;

    case GIMP_PDB_STRINGARRAY:
      stringarr = g_new(gchar *, count);
      for(i=0; i<count; i++) stringarr[i] = g_strdup(StringValuePtr(arr[i]));
      return stringarr;
    default:
      rb_bug("Bad type value in convert_array()");
    }
}
Пример #23
0
static VALUE deque_init(int argc, VALUE *argv, VALUE self)
{
	int len, i;
	VALUE ary;
	
	if(argc == 0) {
		return self;
	}
	else if(argc > 1) {
		rb_raise(rb_eArgError, "wrong number of arguments");
	}
	else {
		ary = rb_check_array_type(argv[0]);
		if(!NIL_P(ary)) {
			len = RARRAY_LEN(ary);
			for (i = 0; i < len; i++) {
				deque_push_back(self, RARRAY_PTR(ary)[i]);
			}
		}
	}
	return self;
}
Пример #24
0
//lcall method that is safe to call during RSRuby initialisation
VALUE RObj_init_lcall(VALUE self, VALUE args){
  SEXP  exp, e, res;
  SEXP  r_obj;
  VALUE obj;

  //Ensure we have an array
  args = rb_check_array_type(args);

  // A SEXP with the function to call and the arguments
  PROTECT(exp = allocVector(LANGSXP, RARRAY_LEN(args)+1));
  e = exp;

  Data_Get_Struct(self, struct SEXPREC, r_obj);

  SETCAR(e, r_obj);
  e = CDR(e);

  // Add the arguments to the SEXP
  if (!make_argl(args, &e)) {
    UNPROTECT(1);
    return Qnil;
  }

  // Evaluate
  PROTECT(res = do_eval_expr(exp));
  if (!res) {
    UNPROTECT(2);
    return Qnil;
  }

  obj = to_ruby_with_mode(res, BASIC_CONVERSION);

  UNPROTECT(2);

  return obj;
}
Пример #25
0
VALUE
rb_grn_check_convert_to_array (VALUE object)
{
    return rb_check_array_type(object);
}
Пример #26
0
static inline int
vm_yield_setup_block_args(rb_thread_t *th, const rb_iseq_t * iseq,
			  int orig_argc, VALUE *argv,
			  const rb_block_t *blockptr)
{
    int i;
    int argc = orig_argc;
    const int m = iseq->argc;
    VALUE ary, arg0;
    int opt_pc = 0;

    th->mark_stack_len = argc;

    /*
     * yield [1, 2]
     *  => {|a|} => a = [1, 2]
     *  => {|a, b|} => a, b = [1, 2]
     */
    arg0 = argv[0];
    if (!(iseq->arg_simple & 0x02) &&          /* exclude {|a|} */
            (m + iseq->arg_post_len) > 0 &&    /* this process is meaningful */
            argc == 1 && !NIL_P(ary = rb_check_array_type(arg0))) { /* rhs is only an array */
        th->mark_stack_len = argc = RARRAY_LENINT(ary);

        CHECK_STACK_OVERFLOW(th->cfp, argc);

        MEMCPY(argv, RARRAY_PTR(ary), VALUE, argc);
    }
    else {
        argv[0] = arg0;
    }

    for (i=argc; i<m; i++) {
        argv[i] = Qnil;
    }

    if (iseq->arg_rest == -1 && iseq->arg_opts == 0) {
        const int arg_size = iseq->arg_size;
        if (arg_size < argc) {
            /*
             * yield 1, 2
             * => {|a|} # truncate
             */
            th->mark_stack_len = argc = arg_size;
        }
    }
    else {
        int r = iseq->arg_rest;

        if (iseq->arg_post_len ||
                iseq->arg_opts) { /* TODO: implement simple version for (iseq->arg_post_len==0 && iseq->arg_opts > 0) */
	    opt_pc = vm_yield_setup_block_args_complex(th, iseq, argc, argv);
        }
        else {
            if (argc < r) {
                /* yield 1
                 * => {|a, b, *r|}
                 */
                for (i=argc; i<r; i++) {
                    argv[i] = Qnil;
                }
                argv[r] = rb_ary_new();
            }
            else {
                argv[r] = rb_ary_new4(argc-r, &argv[r]);
            }
        }

        th->mark_stack_len = iseq->arg_size;
    }

    /* {|&b|} */
    if (iseq->arg_block != -1) {
        VALUE procval = Qnil;

        if (blockptr) {
	    if (blockptr->proc == 0) {
		procval = rb_vm_make_proc(th, blockptr, rb_cProc);
	    }
	    else {
		procval = blockptr->proc;
	    }
        }

        argv[iseq->arg_block] = procval;
    }

    th->mark_stack_len = 0;
    return opt_pc;
}
Пример #27
0
static VALUE so_check_array_type(VALUE self, VALUE ary) {
  return rb_check_array_type(ary);
}