VALUE rb_struct_define(const char *name, ...) { va_list ar; VALUE st, ary; char *mem; ary = rb_ary_tmp_new(0); va_start(ar, name); while ((mem = va_arg(ar, char*)) != 0) { ID slot = rb_intern(mem); rb_ary_push(ary, ID2SYM(slot)); } va_end(ar); if (!name) st = anonymous_struct(rb_cStruct); else st = new_struct(rb_str_new2(name), rb_cStruct); return setup_struct(st, ary); }
static VALUE lazy_cycle(int argc, VALUE *argv, VALUE obj) { VALUE args; int len = rb_long2int((long)argc + 2); if (rb_block_given_p()) { return rb_call_super(argc, argv); } args = rb_ary_tmp_new(len); rb_ary_push(args, obj); rb_ary_push(args, sym_cycle); if (argc > 0) { rb_ary_cat(args, argv, argc); } return lazy_set_method(rb_block_call(rb_cLazy, id_new, len, RARRAY_PTR(args), lazy_cycle_func, args /* prevent from GC */), rb_ary_new4(argc, argv)); }
VALUE rb_struct_new(VALUE klass, ...) { VALUE tmpargs[N_REF_FUNC], *mem = tmpargs; int size, i; va_list args; size = rb_long2int(num_members(klass)); if (size > numberof(tmpargs)) { tmpargs[0] = rb_ary_tmp_new(size); mem = RARRAY_PTR(tmpargs[0]); } va_start(args, klass); for (i=0; i<size; i++) { mem[i] = va_arg(args, VALUE); } va_end(args); return rb_class_new_instance(size, mem, klass); }
static VALUE rb_struct_s_def(int argc, VALUE *argv, VALUE klass) { VALUE name, rest; long i; VALUE st; ID id; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); name = argv[0]; if (SYMBOL_P(name)) { name = Qnil; } else { --argc; ++argv; } rest = rb_ary_tmp_new(argc); for (i=0; i<argc; i++) { id = rb_to_id(argv[i]); RARRAY_ASET(rest, i, ID2SYM(id)); rb_ary_set_len(rest, i+1); } if (NIL_P(name)) { st = anonymous_struct(klass); } else { st = new_struct(name, klass); } setup_struct(st, rest); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } return st; }
void callback(ffi_cif *cif, void *resp, void **args, void *ctx) { VALUE self = (VALUE)ctx; VALUE rbargs = rb_iv_get(self, "@args"); VALUE ctype = rb_iv_get(self, "@ctype"); int argc = RARRAY_LENINT(rbargs); VALUE params = rb_ary_tmp_new(argc); VALUE ret; VALUE cPointer; int i, type; cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); for (i = 0; i < argc; i++) { type = NUM2INT(RARRAY_PTR(rbargs)[i]); switch (type) { case TYPE_VOID: argc = 0; break; case TYPE_INT: rb_ary_push(params, INT2NUM(*(int *)args[i])); break; case -TYPE_INT: rb_ary_push(params, UINT2NUM(*(unsigned int *)args[i])); break; case TYPE_VOIDP: rb_ary_push(params, rb_funcall(cPointer, rb_intern("[]"), 1, PTR2NUM(*(void **)args[i]))); break; case TYPE_LONG: rb_ary_push(params, LONG2NUM(*(long *)args[i])); break; case -TYPE_LONG: rb_ary_push(params, ULONG2NUM(*(unsigned long *)args[i])); break; case TYPE_CHAR: rb_ary_push(params, INT2NUM(*(signed char *)args[i])); break; case -TYPE_CHAR: rb_ary_push(params, UINT2NUM(*(unsigned char *)args[i])); break; case TYPE_SHORT: rb_ary_push(params, INT2NUM(*(signed short *)args[i])); break; case -TYPE_SHORT: rb_ary_push(params, UINT2NUM(*(unsigned short *)args[i])); break; case TYPE_DOUBLE: rb_ary_push(params, rb_float_new(*(double *)args[i])); break; case TYPE_FLOAT: rb_ary_push(params, rb_float_new(*(float *)args[i])); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: rb_ary_push(params, LL2NUM(*(LONG_LONG *)args[i])); break; case -TYPE_LONG_LONG: rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)args[i])); break; #endif default: rb_raise(rb_eRuntimeError, "closure args: %d", type); } } ret = rb_funcall2(self, rb_intern("call"), argc, RARRAY_PTR(params)); RB_GC_GUARD(params); type = NUM2INT(ctype); switch (type) { case TYPE_VOID: break; case TYPE_LONG: *(long *)resp = NUM2LONG(ret); break; case -TYPE_LONG: *(unsigned long *)resp = NUM2ULONG(ret); break; case TYPE_CHAR: case TYPE_SHORT: case TYPE_INT: *(ffi_sarg *)resp = NUM2INT(ret); break; case -TYPE_CHAR: case -TYPE_SHORT: case -TYPE_INT: *(ffi_arg *)resp = NUM2UINT(ret); break; case TYPE_VOIDP: *(void **)resp = NUM2PTR(ret); break; case TYPE_DOUBLE: *(double *)resp = NUM2DBL(ret); break; case TYPE_FLOAT: *(float *)resp = (float)NUM2DBL(ret); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: *(LONG_LONG *)resp = NUM2LL(ret); break; case -TYPE_LONG_LONG: *(unsigned LONG_LONG *)resp = NUM2ULL(ret); break; #endif default: rb_raise(rb_eRuntimeError, "closure retval: %d", type); } }
static VALUE ary_buf_new(void) { return rb_ary_tmp_new(1); }
static void args_setup_kw_parameters(VALUE* const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords, const rb_iseq_t * const iseq, VALUE * const locals) { const ID *acceptable_keywords = iseq->body->param.keyword->table; const int req_key_num = iseq->body->param.keyword->required_num; const int key_num = iseq->body->param.keyword->num; const VALUE * const default_values = iseq->body->param.keyword->default_values; VALUE missing = 0; int i, di, found = 0; int unspecified_bits = 0; VALUE unspecified_bits_value = Qnil; for (i=0; i<req_key_num; i++) { ID key = acceptable_keywords[i]; if (args_setup_kw_parameters_lookup(key, &locals[i], passed_keywords, passed_values, passed_keyword_len)) { found++; } else { if (!missing) missing = rb_ary_tmp_new(1); rb_ary_push(missing, ID2SYM(key)); } } if (missing) argument_kw_error(GET_THREAD(), iseq, "missing", missing); for (di=0; i<key_num; i++, di++) { if (args_setup_kw_parameters_lookup(acceptable_keywords[i], &locals[i], passed_keywords, passed_values, passed_keyword_len)) { found++; } else { if (default_values[di] == Qundef) { locals[i] = Qnil; if (LIKELY(i < 32)) { /* TODO: 32 -> Fixnum's max bits */ unspecified_bits |= 0x01 << di; } else { if (NIL_P(unspecified_bits_value)) { /* fixnum -> hash */ int j; unspecified_bits_value = rb_hash_new(); for (j=0; j<32; j++) { if (unspecified_bits & (0x01 << j)) { rb_hash_aset(unspecified_bits_value, INT2FIX(j), Qtrue); } } } rb_hash_aset(unspecified_bits_value, INT2FIX(di), Qtrue); } } else { locals[i] = default_values[di]; } } } if (iseq->body->param.flags.has_kwrest) { const int rest_hash_index = key_num + 1; locals[rest_hash_index] = make_unused_kw_hash(passed_keywords, passed_keyword_len, passed_values, FALSE); } else { if (found != passed_keyword_len) { VALUE keys = make_unused_kw_hash(passed_keywords, passed_keyword_len, passed_values, TRUE); argument_kw_error(GET_THREAD(), iseq, "unknown", keys); } } if (NIL_P(unspecified_bits_value)) { unspecified_bits_value = INT2FIX(unspecified_bits); } locals[key_num] = unspecified_bits_value; }