예제 #1
0
파일: hash.c 프로젝트: Jaharmi/MacRuby
static VALUE
hash_equal(VALUE hash1, VALUE hash2, bool eql)
{
    if (hash1 == hash2) {
	return Qtrue;
    }
    if (TYPE(hash2) != T_HASH) {
	if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
	    return Qfalse;
	}
	if (eql) {
	    return rb_eql(hash2, hash1);
	}
	else {
	    return rb_equal(hash2, hash1);
	}
    }
    if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) {
	return Qfalse;
    }
    if (IS_RHASH(hash2)) {
	struct equal_data data;
	data.tbl = RHASH(hash2)->tbl;
	data.eql = eql;
	return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data);
    }
    else {
	return CFEqual((CFTypeRef)hash1, (CFTypeRef)hash2) ? Qtrue : Qfalse;
    }
}
예제 #2
0
/*
 * call-seq: to_json(state = nil, depth = 0)
 *
 * Returns a JSON string containing a JSON object, that is unparsed from
 * this Hash instance.
 * _state_ is a JSON::State object, that can also be used to configure the
 * produced JSON string output further.
 * _depth_ is used to find out nesting depth, to indent accordingly.
 */
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
{
    VALUE Vstate, Vdepth, result;
    long depth;

    rb_scan_args(argc, argv, "02", &Vstate, &Vdepth);
    depth = NIL_P(Vdepth) ? 0 : FIX2LONG(Vdepth);
    if (NIL_P(Vstate)) {
        long len = RHASH_SIZE(self);
        result = rb_str_buf_new(len);
        rb_str_buf_cat2(result, "{");
        rb_hash_foreach(self, hash_to_json_i, result);
        rb_str_buf_cat2(result, "}");
    } else {
        GET_STATE(Vstate);
        check_max_nesting(state, depth);
        if (state->check_circular) {
            VALUE self_id = rb_obj_id(self);
            if (RTEST(rb_hash_aref(state->seen, self_id))) {
                rb_raise(eCircularDatastructure,
                        "circular data structures not supported!");
            }
            rb_hash_aset(state->seen, self_id, Qtrue);
            result = mHash_json_transfrom(self, Vstate, LONG2FIX(depth));
            rb_hash_delete(state->seen, self_id);
        } else {
            result = mHash_json_transfrom(self, Vstate, LONG2FIX(depth));
        }
    }
    OBJ_INFECT(result, self);
    FORCE_UTF8(result);
    return result;
}
예제 #3
0
void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash)
{
	struct mochilo_hash_pack hash_pack;
	long size = RHASH_SIZE(rb_hash);

	hash_pack.buf = buf;

	if (size < 0x10) {
		uint8_t lead = 0x80 | size;
		mochilo_buf_putc(buf, lead);
	}

	else if (size < 0x10000) {
		uint16_t lead = size;
		mochilo_buf_putc(buf, MSGPACK_T_MAP16);
		mochilo_buf_put16be(buf, &lead);
	}

	else {
		mochilo_buf_putc(buf, MSGPACK_T_MAP32);
		mochilo_buf_put32be(buf, &size);
	}

	rb_hash_foreach(rb_hash, &hash_callback, (VALUE)&hash_pack);
}
예제 #4
0
파일: rubyCall.c 프로젝트: mnatale/RRuby
SEXP
R_rb_hash_size(SEXP r_obj)
{
    VALUE obj;
    obj = getRubyObjectFromR(r_obj);
    return(ScalarInteger(RHASH_SIZE(obj)));
}
예제 #5
0
    static void
cb_params_store_parse_arguments(struct params_st *params, int argc, VALUE argv)
{
    VALUE keys;

    if (argc < 1) {
        rb_raise(rb_eArgError, "the key and value must be specified");
    }
    switch (argc) {
        case 1:
            keys = RARRAY_PTR(argv)[0];
            switch(TYPE(keys)) {
                case T_HASH:
                    /* key-value pairs */
                    cb_params_store_alloc(params, RHASH_SIZE(keys));
                    rb_hash_foreach(keys, cb_params_store_extract_keys_i,
                            (VALUE)params);
                    break;
                default:
                    rb_raise(rb_eArgError, "there must be either Hash with key-value pairs"
                            " or two separate arguments: key and value");
            }
            break;
        case 2:
            /* just key and value */
            cb_params_store_alloc(params, 1);
            cb_params_store_init_item(params, 0, RARRAY_PTR(argv)[0], RARRAY_PTR(argv)[1],
                    params->cmd.store.flags, params->cmd.store.cas, params->cmd.store.ttl);
            break;
        default:
            rb_raise(rb_eArgError, "too many arguments");
    }
}
예제 #6
0
파일: native.c 프로젝트: louismullie/birch
/* Boolean - does the node have features? */
static VALUE birch_has_features(VALUE self) {
	VALUE features;
	features = rb_iv_get(self, "@features");
  if (RHASH_SIZE(features) == 0) {
		return Qfalse;
	} else { return Qtrue; }
}
예제 #7
0
/*
 * Document-method: Hash#to_msgpack
 *
 * call-seq:
 *   hash.to_msgpack(out = '') -> String
 *
 * Serializes the Hash into raw bytes.
 * This calls to_msgpack method reflectively for internal keys and values.
 */
static VALUE MessagePack_Hash_to_msgpack(int argc, VALUE *argv, VALUE self)
{
    ARG_BUFFER(out, argc, argv);
    msgpack_pack_map(out, RHASH_SIZE(self));
    rb_hash_foreach(self, MessagePack_Hash_to_msgpack_foreach, out);
    return out;
}
예제 #8
0
파일: class.c 프로젝트: ksperling/ruby
int
rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
{
    int i = 0, j;
    int rest = 0;
    VALUE missing = Qnil;
    st_data_t key;

#define extract_kwarg(keyword, val) \
    (key = (st_data_t)(keyword), values ? \
     st_delete(rb_hash_tbl_raw(keyword_hash), &key, (val)) : \
     st_lookup(rb_hash_tbl_raw(keyword_hash), key, (val)))

    if (NIL_P(keyword_hash)) keyword_hash = 0;

    if (optional < 0) {
	rest = 1;
	optional = -1-optional;
    }
    if (values) {
	for (j = 0; j < required + optional; j++) {
	    values[j] = Qundef;
	}
    }
    if (required) {
	for (; i < required; i++) {
	    VALUE keyword = ID2SYM(table[i]);
	    if (keyword_hash) {
		st_data_t val;
		if (extract_kwarg(keyword, &val)) {
		    if (values) values[i] = (VALUE)val;
		    continue;
		}
	    }
	    if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
	    rb_ary_push(missing, keyword);
	}
	if (!NIL_P(missing)) {
	    keyword_error("missing", missing);
	}
    }
    j = i;
    if (optional && keyword_hash) {
	for (i = 0; i < optional; i++) {
	    st_data_t val;
	    if (extract_kwarg(ID2SYM(table[required+i]), &val)) {
		if (values) values[required+i] = (VALUE)val;
		j++;
	    }
	}
    }
    if (!rest && keyword_hash) {
	if (RHASH_SIZE(keyword_hash) > (unsigned int)j) {
	    unknown_keyword_error(keyword_hash, table, required+optional);
	}
    }
    return j;
#undef extract_kwarg
}
예제 #9
0
/*
 * Document-method: Hash#to_msgpack
 *
 * call-seq:
 *   hash.to_msgpack(out = '') -> String
 *
 * Serializes the Hash into raw bytes.
 * This calls to_msgpack method reflectively for internal keys and values.
 */
static VALUE MessagePack_Hash_to_msgpack(int argc, VALUE *argv, VALUE self)
{
	ARG_BUFFER(out, argc, argv);
	// FIXME check sizeof(st_index_t) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX
	msgpack_pack_map(out, (unsigned int)RHASH_SIZE(self));
	rb_hash_foreach(self, MessagePack_Hash_to_msgpack_foreach, out);
	return out;
}
예제 #10
0
파일: hash.c 프로젝트: Zyxwvu/mruby
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
{
  if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
  if (mrb_type(hash2) != MRB_TT_HASH) {
      if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
          return mrb_false_value();
      }
      if (eql)
          return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1));
      else
          return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
  }
  if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value();
  if (!RHASH(hash1)->ht || !RHASH(hash2)->ht) return mrb_true_value();

  return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, (void*)0);
}
예제 #11
0
static void pack_hash_event(rbkit_hash_event *event, msgpack_packer *packer) {
  VALUE hash;
  int size;
  msgpack_pack_map(packer, 3);
  pack_event_header(packer, event->event_header.event_type);
  hash = event->hash;
  size = (int)RHASH_SIZE(hash);
  msgpack_pack_int(packer, rbkit_message_field_payload);
  msgpack_pack_map(packer, size);
  rb_hash_foreach(hash, hash_pack_iterator, (VALUE)packer);
}
예제 #12
0
static VALUE ov_http_client_send(VALUE self, VALUE request) {
    ov_http_client_object* ptr;

    /* Get the pointer to the native object and check that it isn't closed: */
    ov_http_client_ptr(self, ptr);
    ov_http_client_check_closed(ptr);

    /* If the limit hasn't been reached then submit the request directly to libcurl, otherwise put it in the queue: */
    if (RHASH_SIZE(ptr->pending) < ptr->limit) {
        ov_http_client_submit(self, request);
    }
    else {
        rb_ary_push(ptr->queue, request);
    }

    return Qnil;
}
예제 #13
0
static VALUE ov_http_client_build_url( VALUE url, VALUE query) {
    /* Copy the URL: */
    if (NIL_P(url)) {
        rb_raise(ov_error_class, "The 'url' parameter can't be nil");
    }
    Check_Type(url, T_STRING);

    /* Append the query: */
    if (!NIL_P(query)) {
        Check_Type(query, T_HASH);
        if (RHASH_SIZE(query) > 0) {
            url = rb_sprintf("%"PRIsVALUE"?%"PRIsVALUE"", url, rb_funcall(URI_CLASS, ENCODE_WWW_FORM_ID, 1, query));
        }
    }

    return url;
}
예제 #14
0
    static void
cb_params_get_parse_arguments(struct params_st *params, int argc, VALUE argv)
{
    lcb_size_t ii;

    if (argc < 1) {
        rb_raise(rb_eArgError, "must be at least one key");
    }
    if (argc == 1) {
        VALUE keys = RARRAY_PTR(argv)[0];
        switch(TYPE(keys)) {
            case T_ARRAY:
                /* array of keys as a first argument */
                params->cmd.get.array = 1;
                cb_params_get_alloc(params, RARRAY_LEN(keys));
                for (ii = 0; ii < params->cmd.get.num; ++ii) {
                    rb_ary_push(params->cmd.get.keys_ary, RARRAY_PTR(keys)[ii]);
                    cb_params_get_init_item(params, ii, RARRAY_PTR(keys)[ii], params->cmd.get.ttl);
                }
                break;
            case T_HASH:
                /* key-ttl pairs */
                if (params->cmd.get.replica) {
                    rb_raise(rb_eArgError, "must be either list of key or single key");
                }
                params->cmd.get.gat = 1;
                cb_params_get_alloc(params, RHASH_SIZE(keys));
                rb_hash_foreach(keys, cb_params_get_extract_keys_i, (VALUE)params);
                break;
            default:
                /* single key */
                cb_params_get_alloc(params, 1);
                rb_ary_push(params->cmd.get.keys_ary, keys);
                cb_params_get_init_item(params, 0, keys, params->cmd.get.ttl);
        }
    } else {
        /* just list of arguments */
        cb_params_get_alloc(params, argc);
        for (ii = 0; ii < params->cmd.get.num; ++ii) {
            rb_ary_push(params->cmd.get.keys_ary, RARRAY_PTR(argv)[ii]);
            cb_params_get_init_item(params, ii, RARRAY_PTR(argv)[ii], params->cmd.get.ttl);
        }
    }
}
예제 #15
0
static VALUE ov_http_client_wait(VALUE self, VALUE request) {
    VALUE next;
    VALUE result;
    ov_http_client_object* ptr;
    ov_http_client_wait_context context;

    /* Get the pointer to the native object and check that it isn't closed: */
    ov_http_client_ptr(self, ptr);
    ov_http_client_check_closed(ptr);

    /* Work till the transfer has been completed. */
    context.handle = ptr->handle;
    context.code = CURLE_OK;
    context.cancel = false;
    for (;;) {
        /* Move requests from the queue to libcurl: */
        while (RARRAY_LEN(ptr->queue) > 0 && RHASH_SIZE(ptr->pending) < ptr->limit) {
            next = rb_ary_shift(ptr->queue);
            ov_http_client_submit(self, next);
        }

        /* Check if the response is already available, if so then return it: */
        result = rb_hash_delete(ptr->completed, request);
        if (!NIL_P(result)) {
            return result;
        }

        /* If the response isn't available yet, then do some real work: */
        rb_thread_call_without_gvl(
            ov_http_client_wait_task,
            &context,
            ov_http_client_wait_cancel,
            &context
        );
        if (context.cancel) {
            return Qnil;
        }
        if (context.code != CURLE_OK) {
            rb_raise(ov_error_class, "Unexpected error while waiting: %s", curl_easy_strerror(context.code));
        }
    }

    return Qnil;
}
예제 #16
0
    static void
cb_params_unlock_parse_arguments(struct params_st *params, int argc, VALUE argv)
{
    if (argc == 1) {
        VALUE keys = RARRAY_PTR(argv)[0];
        switch(TYPE(keys)) {
            case T_HASH:
                /* key-cas pairs */
                cb_params_unlock_alloc(params, RHASH_SIZE(keys));
                rb_hash_foreach(keys, cb_params_unlock_extract_keys_i, (VALUE)params);
                break;
            default:
                /* single key */
                cb_params_unlock_alloc(params, 1);
                cb_params_unlock_init_item(params, 0, keys, params->cmd.unlock.cas);
        }
    } else {
        rb_raise(rb_eArgError, "must be either Hash or single key with cas option");
    }
}
예제 #17
0
inline static VALUE mHash_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) {
    long depth, len = RHASH_SIZE(self);
    VALUE result;
    GET_STATE(Vstate);

    depth = 1 + FIX2LONG(Vdepth);
    result = rb_str_buf_new(len);
    state->memo = result;
    state->depth = LONG2FIX(depth);
    state->flag = 0;
    rb_str_buf_cat2(result, "{");
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    rb_hash_foreach(self, hash_to_json_state_i, Vstate);
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    if (RSTRING_LEN(state->object_nl)) {
        rb_str_buf_append(result, rb_str_times(state->indent, Vdepth));
    }
    rb_str_buf_cat2(result, "}");
    return result;
}
예제 #18
0
void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
{
    /* actual return type of RHASH_SIZE is long (if SIZEOF_LONG == SIZEOF_VOIDP
     * or long long (if SIZEOF_LONG_LONG == SIZEOF_VOIDP. See st.h. */
    unsigned long len = RHASH_SIZE(v);
    if(len > 0xffffffffUL) {
        rb_raise(rb_eArgError, "size of array is too long to pack: %ld bytes should be <= %lu", len, 0xffffffffUL);
    }
    unsigned int len32 = (unsigned int)len;
    msgpack_packer_write_map_header(pk, len32);

#ifdef RUBINIUS
    VALUE iter = rb_funcall(v, s_to_iter, 0);
    VALUE entry = Qnil;
    while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) {
        VALUE key = rb_funcall(entry, s_key, 0);
        VALUE val = rb_funcall(entry, s_value, 0);
        write_hash_foreach(key, val, (VALUE) pk);
    }
#else
    rb_hash_foreach(v, write_hash_foreach, (VALUE) pk);
#endif
}
예제 #19
0
파일: common.c 프로젝트: agx/ruby-libvirt
VALUE ruby_libvirt_set_typed_parameters(VALUE d, VALUE input,
                                        unsigned int flags, void *opaque,
                                        struct ruby_libvirt_typed_param *allowed,
                                        unsigned int num_allowed,
                                        const char *(*set_cb)(VALUE d,
                                                              unsigned int flags,
                                                              virTypedParameterPtr params,
                                                              int nparams,
                                                              void *opaque))
{
    const char *errname;
    struct ruby_libvirt_parameter_assign_args args;
    unsigned long hashsize;

    /* make sure input is a hash */
    Check_Type(input, T_HASH);

    hashsize = RHASH_SIZE(input);

    if (hashsize == 0) {
        return Qnil;
    }

    args.allowed = allowed;
    args.num_allowed = num_allowed;
    args.params = alloca(sizeof(virTypedParameter) * hashsize);
    args.i = 0;

    rb_hash_foreach(input, ruby_libvirt_typed_parameter_assign, (VALUE)&args);

    errname = set_cb(d, flags, args.params, args.i, opaque);
    ruby_libvirt_raise_error_if(errname != NULL, e_RetrieveError, errname,
                                ruby_libvirt_connect_get(d));

    return Qnil;
}
예제 #20
0
VALUE
rb_hash_notempty_p( VALUE hash)
{
    return RHASH_SIZE( hash) == 0 ? Qnil : hash;
}
예제 #21
0
파일: watchman.c 프로젝트: jiayong/myvim
/**
 * Encodes and appends the hash `hash` to `w`
 */
void watchman_dump_hash(watchman_t *w, VALUE hash) {
    watchman_append(w, &watchman_hash_marker, sizeof(watchman_hash_marker));
    watchman_dump_int(w, RHASH_SIZE(hash));
    rb_hash_foreach(hash, watchman_dump_hash_iterator, (VALUE)w);
}
예제 #22
0
static int
setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq,
			 struct rb_calling_info *const calling,
			 const struct rb_call_info *ci,
			 VALUE * const locals, const enum arg_setup_type arg_setup_type)
{
    const int min_argc = iseq->body->param.lead_num + iseq->body->param.post_num;
    const int max_argc = (iseq->body->param.flags.has_rest == FALSE) ? min_argc + iseq->body->param.opt_num : UNLIMITED_ARGUMENTS;
    int opt_pc = 0;
    int given_argc;
    struct args_info args_body, *args;
    VALUE keyword_hash = Qnil;
    VALUE * const orig_sp = th->cfp->sp;
    unsigned int i;

    /*
     * Extend SP for GC.
     *
     * [pushed values] [uninitialized values]
     * <- ci->argc -->
     * <- iseq->body->param.size------------>
     * ^ locals        ^ sp
     *
     * =>
     * [pushed values] [initialized values  ]
     * <- ci->argc -->
     * <- iseq->body->param.size------------>
     * ^ locals                             ^ sp
     */
    for (i=calling->argc; i<iseq->body->param.size; i++) {
	locals[i] = Qnil;
    }
    th->cfp->sp = &locals[i];

    /* setup args */
    args = &args_body;
    given_argc = args->argc = calling->argc;
    args->argv = locals;

    if (ci->flag & VM_CALL_KWARG) {
	args->kw_arg = ((struct rb_call_info_with_kwarg *)ci)->kw_arg;

	if (iseq->body->param.flags.has_kw) {
	    int kw_len = args->kw_arg->keyword_len;
	    /* copy kw_argv */
	    args->kw_argv = ALLOCA_N(VALUE, kw_len);
	    args->argc -= kw_len;
	    given_argc -= kw_len;
	    MEMCPY(args->kw_argv, locals + args->argc, VALUE, kw_len);
	}
	else {
	    args->kw_argv = NULL;
	    given_argc = args_kw_argv_to_hash(args);
	}
    }
    else {
	args->kw_arg = NULL;
	args->kw_argv = NULL;
    }

    if (ci->flag & VM_CALL_ARGS_SPLAT) {
	args->rest = locals[--args->argc];
	args->rest_index = 0;
	given_argc += RARRAY_LENINT(args->rest) - 1;
    }
    else {
	args->rest = Qfalse;
    }

    switch (arg_setup_type) {
      case arg_setup_method:
	break; /* do nothing special */
      case arg_setup_block:
	if (given_argc == 1 &&
	    (min_argc > 0 || iseq->body->param.opt_num > 1 ||
	     iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
	    !iseq->body->param.flags.ambiguous_param0 &&
	    args_check_block_arg0(args, th)) {
	    given_argc = RARRAY_LENINT(args->rest);
	}
	break;
      case arg_setup_lambda:
	if (given_argc == 1 &&
	    given_argc != iseq->body->param.lead_num &&
	    !iseq->body->param.flags.has_rest &&
	    args_check_block_arg0(args, th)) {
	    given_argc = RARRAY_LENINT(args->rest);
	}
    }

    /* argc check */
    if (given_argc < min_argc) {
	if (given_argc == min_argc - 1 && args->kw_argv) {
	    args_stored_kw_argv_to_hash(args);
	    given_argc = args_argc(args);
	}
	else {
	    if (arg_setup_type == arg_setup_block) {
		CHECK_VM_STACK_OVERFLOW(th->cfp, min_argc);
		given_argc = min_argc;
		args_extend(args, min_argc);
	    }
	    else {
		argument_arity_error(th, iseq, given_argc, min_argc, max_argc);
	    }
	}
    }

    if (given_argc > min_argc &&
	(iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) &&
	args->kw_argv == NULL) {
	if (args_pop_keyword_hash(args, &keyword_hash, th)) {
	    given_argc--;
	}
    }

    if (given_argc > max_argc && max_argc != UNLIMITED_ARGUMENTS) {
	if (arg_setup_type == arg_setup_block) {
	    /* truncate */
	    args_reduce(args, given_argc - max_argc);
	    given_argc = max_argc;
	}
	else {
	    argument_arity_error(th, iseq, given_argc, min_argc, max_argc);
	}
    }

    if (iseq->body->param.flags.has_lead) {
	args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0);
    }

    if (iseq->body->param.flags.has_post) {
	args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start);
    }

    if (iseq->body->param.flags.has_opt) {
	int opt = args_setup_opt_parameters(args, iseq->body->param.opt_num, locals + iseq->body->param.lead_num);
	opt_pc = (int)iseq->body->param.opt_table[opt];
    }

    if (iseq->body->param.flags.has_rest) {
	args_setup_rest_parameter(args, locals + iseq->body->param.rest_start);
    }

    if (iseq->body->param.flags.has_kw) {
	VALUE * const klocals = locals + iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num;

	if (args->kw_argv != NULL) {
	    const struct rb_call_info_kw_arg *kw_arg = args->kw_arg;
	    args_setup_kw_parameters(args->kw_argv, kw_arg->keyword_len, kw_arg->keywords, iseq, klocals);
	}
	else if (!NIL_P(keyword_hash)) {
	    int kw_len = rb_long2int(RHASH_SIZE(keyword_hash));
	    struct fill_values_arg arg;
	    /* copy kw_argv */
	    arg.keys = args->kw_argv = ALLOCA_N(VALUE, kw_len * 2);
	    arg.vals = arg.keys + kw_len;
	    arg.argc = 0;
	    rb_hash_foreach(keyword_hash, fill_keys_values, (VALUE)&arg);
	    VM_ASSERT(arg.argc == kw_len);
	    args_setup_kw_parameters(arg.vals, kw_len, arg.keys, iseq, klocals);
	}
	else {
	    VM_ASSERT(args_argc(args) == 0);
	    args_setup_kw_parameters(NULL, 0, NULL, iseq, klocals);
	}
    }
    else if (iseq->body->param.flags.has_kwrest) {
	args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start);
    }

    if (iseq->body->param.flags.has_block) {
	args_setup_block_parameter(th, calling, locals + iseq->body->param.block_start);
    }

#if 0
    {
	int i;
	for (i=0; i<iseq->body->param.size; i++) {
	    fprintf(stderr, "local[%d] = %p\n", i, (void *)locals[i]);
	}
    }
#endif

    th->cfp->sp = orig_sp;
    return opt_pc;
}