17 #if !defined(_MSC_VER) || !defined(MJIT_HEADER)
61 args_extend(
struct args_info *args,
const int min_argc)
73 for (i=args->
argc; i<min_argc; i++) {
80 args_reduce(
struct args_info *args,
int over_argc)
85 if (
len > over_argc) {
97 args->
argc -= over_argc;
101 args_check_block_arg0(
struct args_info *args)
109 else if (args->
argc == 1) {
112 args->
argv[0] = arg0;
160 else if (args->
argc > 0) {
168 static inline const VALUE *
190 #define KW_HASH_HAS_NO_KEYS 0
191 #define KW_HASH_HAS_SYMBOL_KEY 1
192 #define KW_HASH_HAS_OTHER_KEY 2
193 #define KW_HASH_HAS_BOTH_KEYS 3
208 keyword_hash_symbol_other(
VALUE hash)
227 keyword_hash_split(
VALUE *kw_hash_ptr,
VALUE *rest_hash_ptr)
234 keyword_hash_p(
VALUE *kw_hash_ptr,
VALUE *rest_hash_ptr,
int check_only_symbol)
238 if (!
NIL_P(*rest_hash_ptr)) {
239 if (check_only_symbol) {
240 switch (keyword_hash_symbol_other(*rest_hash_ptr)) {
249 keyword_hash_split(kw_hash_ptr, rest_hash_ptr);
253 *kw_hash_ptr = *rest_hash_ptr;
264 args_pop_keyword_hash(
struct args_info *args,
VALUE *kw_hash_ptr,
int check_only_symbol)
271 *kw_hash_ptr = args->
argv[args->
argc-1];
273 if (keyword_hash_p(kw_hash_ptr, &rest_hash, check_only_symbol)) {
275 args->
argv[args->
argc-1] = rest_hash;
289 if (keyword_hash_p(kw_hash_ptr, &rest_hash, check_only_symbol)) {
309 args_kw_argv_to_hash(
struct args_info *args)
315 const int kw_start = args->
argc - kw_len;
316 const VALUE *
const kw_argv = args->
argv + kw_start;
319 args->
argc = kw_start + 1;
320 for (i=0; i<kw_len; i++) {
330 args_stored_kw_argv_to_hash(
struct args_info *args)
335 const int passed_keyword_len = kw_arg->
keyword_len;
338 for (i=0; i<passed_keyword_len; i++) {
362 const VALUE *
argv = args_rest_argv(args);
364 for (i=args->
argc, j=0; i<
argc; i++, j++) {
382 args_setup_opt_parameters(
struct args_info *args,
int opt_max,
VALUE *locals)
386 if (args->
argc >= opt_max) {
387 args->
argc -= opt_max;
388 args->
argv += opt_max;
406 for (j=i; j<opt_max; j++) {
417 *locals = args_rest_array(args);
421 make_unknown_kw_hash(
const VALUE *passed_keywords,
int passed_keyword_len,
const VALUE *kw_argv)
426 for (i=0; i<passed_keyword_len; i++) {
427 if (kw_argv[i] !=
Qundef) {
435 make_rest_kw_hash(
const VALUE *passed_keywords,
int passed_keyword_len,
const VALUE *kw_argv)
440 for (i=0; i<passed_keyword_len; i++) {
441 if (kw_argv[i] !=
Qundef) {
449 args_setup_kw_parameters_lookup(
const ID key,
VALUE *
ptr,
const VALUE *
const passed_keywords,
VALUE *passed_values,
const int passed_keyword_len)
454 for (i=0; i<passed_keyword_len; i++) {
455 if (keyname == passed_keywords[i]) {
456 *
ptr = passed_values[i];
457 passed_values[i] =
Qundef;
465 #define KW_SPECIFIED_BITS_MAX (32-1)
469 VALUE *
const passed_values,
const int passed_keyword_len,
const VALUE *
const passed_keywords,
477 int i, di, found = 0;
478 int unspecified_bits = 0;
481 for (i=0; i<req_key_num; i++) {
482 ID key = acceptable_keywords[i];
483 if (args_setup_kw_parameters_lookup(
key, &locals[i], passed_keywords, passed_values, passed_keyword_len)) {
492 if (missing) argument_kw_error(ec, iseq,
"missing", missing);
494 for (di=0; i<key_num; i++, di++) {
495 if (args_setup_kw_parameters_lookup(acceptable_keywords[i], &locals[i], passed_keywords, passed_values, passed_keyword_len)) {
499 if (default_values[di] ==
Qundef) {
503 unspecified_bits |= 0x01 << di;
506 if (
NIL_P(unspecified_bits_value)) {
512 if (unspecified_bits & (0x01 << j)) {
521 locals[i] = default_values[di];
527 const int rest_hash_index = key_num + 1;
528 locals[rest_hash_index] = make_rest_kw_hash(passed_keywords, passed_keyword_len, passed_values);
531 if (found != passed_keyword_len) {
532 VALUE keys = make_unknown_kw_hash(passed_keywords, passed_keyword_len, passed_values);
533 argument_kw_error(ec, iseq,
"unknown", keys);
537 if (
NIL_P(unspecified_bits_value)) {
538 unspecified_bits_value =
INT2FIX(unspecified_bits);
540 locals[key_num] = unspecified_bits_value;
544 args_setup_kw_rest_parameter(
VALUE keyword_hash,
VALUE *locals)
573 ignore_keyword_hash_p(
VALUE keyword_hash,
const rb_iseq_t *
const iseq)
595 static st_table *caller_to_callees = 0;
612 if (!caller_to_callees) {
617 if (
st_lookup(caller_to_callees, caller, &val)) {
622 if (val ==
callee)
return 1;
644 if (rb_warn_check(ec, iseq))
return;
648 rb_warn(
"Passing the keyword argument as the last hash parameter is deprecated");
654 rb_warn(
"Passing the keyword argument for `%"PRIsVALUE"' as the last hash parameter is deprecated",
658 rb_warn(
"Passing the keyword argument as the last hash parameter is deprecated");
665 "The called method is defined here");
673 if (rb_warn_check(ec, iseq))
return;
679 rb_warn(
"Splitting the last argument for `%"PRIsVALUE"' into positional and keyword parameters is deprecated",
683 rb_warn(
"Splitting the last argument into positional and keyword parameters is deprecated");
690 "The called method is defined here");
698 if (rb_warn_check(ec, iseq))
return;
704 rb_warn(
"Using the last argument for `%"PRIsVALUE"' as keyword parameters is deprecated; maybe ** should be added to the call",
708 rb_warn(
"Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call");
715 "The called method is defined here");
729 int kw_splat =
FALSE;
731 int opt_pc = 0, allow_autosplat = !kw_flag;
736 int remove_empty_keyword_hash = 1;
737 VALUE flag_keyword_hash = 0;
754 for (i=calling->
argc; i<iseq->body->param.size; i++) {
757 ec->
cfp->
sp = &locals[i];
761 given_argc = args->
argc = calling->
argc;
772 args->
argc -= kw_len;
773 given_argc -= kw_len;
778 given_argc = args_kw_argv_to_hash(args);
788 remove_empty_keyword_hash = 0;
797 given_argc +=
len - 1;
800 if (!kw_flag &&
len > 0) {
806 remove_empty_keyword_hash = 0;
815 if (
len > 0 && ignore_keyword_hash_p(rest_last, iseq)) {
816 if (given_argc != min_argc) {
817 if (remove_empty_keyword_hash) {
828 flag_keyword_hash = rest_last;
832 rb_warn_keyword_to_last_hash(ec, calling,
ci, iseq);
835 else if (!remove_empty_keyword_hash && rest_last) {
836 flag_keyword_hash = rest_last;
843 if (ignore_keyword_hash_p(last_arg, iseq)) {
844 if (given_argc != min_argc) {
845 if (remove_empty_keyword_hash) {
853 args->
argv[args->
argc-1] = last_arg;
855 flag_keyword_hash = last_arg;
859 rb_warn_keyword_to_last_hash(ec, calling,
ci, iseq);
862 else if (!remove_empty_keyword_hash) {
863 flag_keyword_hash = args->
argv[args->
argc-1];
881 if (given_argc == 1 &&
886 args_check_block_arg0(args)) {
893 if (given_argc < min_argc) {
894 if (given_argc == min_argc - 1 && args->
kw_argv) {
895 args_stored_kw_argv_to_hash(args);
896 given_argc = args_argc(args);
901 given_argc = min_argc;
902 args_extend(args, min_argc);
905 argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
914 (kw_splat && given_argc > max_argc)) &&
916 if (given_argc > min_argc) {
922 if (args_pop_keyword_hash(args, &keyword_hash, check_only_symbol)) {
925 else if (check_only_symbol) {
926 if (keyword_hash !=
Qnil) {
927 rb_warn_split_last_hash_to_keyword(ec, calling, ci, iseq);
930 rb_warn_keyword_to_last_hash(ec, calling, ci, iseq);
934 else if (args_pop_keyword_hash(args, &keyword_hash, 1)) {
939 rb_warn_last_hash_to_keyword(ec, calling, ci, iseq);
942 else if (keyword_hash !=
Qnil) {
943 rb_warn_split_last_hash_to_keyword(ec, calling, ci, iseq);
946 else if (given_argc == min_argc && kw_flag) {
947 rb_warn_keyword_to_last_hash(ec, calling, ci, iseq);
954 args_reduce(args, given_argc - max_argc);
955 given_argc = max_argc;
958 argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
990 else if (!
NIL_P(keyword_hash)) {
995 arg.vals = arg.keys + kw_len;
999 args_setup_kw_parameters(ec, iseq, arg.vals, kw_len, arg.keys, klocals);
1003 args_setup_kw_parameters(ec, iseq,
NULL, 0,
NULL, klocals);
1007 args_setup_kw_rest_parameter(keyword_hash, locals + iseq->
body->
param.
keyword->rest_start);
1010 argument_kw_error(ec, iseq,
"unknown",
rb_hash_keys(keyword_hash));
1026 fprintf(stderr,
"local[%d] = %p\n", i, (
void *)locals[i]);
1031 ec->
cfp->
sp = orig_sp;
1046 ec->
cfp->
sp, 0, 0 );
1063 VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
1066 const ID *keywords = kw->table;
1067 int req_key_num = kw->required_num;
1068 if (req_key_num > 0) {
1069 static const char required[] =
"; required keywords";
1072 rb_str_cat(mesg, required,
sizeof(required) - 1 - (req_key_num == 1));
1078 }
while (--req_key_num);
1082 raise_argument_error(ec, iseq, exc);
1107 for (i = 0; i <
len; i++) {
1108 *cfp->
sp++ =
ptr[i];
1110 calling->
argc += i - 1;
1124 for (i=0; i<kw_len; i++) {
1129 cfp->
sp -= kw_len - 1;
1130 calling->
argc -= kw_len - 1;
1135 vm_to_proc(
VALUE proc)
1152 "wrong argument type %s (expected Proc)",
1191 if (!
NIL_P(blockarg)) {
1192 vm_passed_block_handler_set(ec, blockarg);
1210 VALUE block_code = *(--reg_cfp->
sp);
1212 if (
NIL_P(block_code)) {
1217 VALUE handler = VM_CF_BLOCK_HANDLER(reg_cfp);
1218 reg_cfp->
block_code = (
const void *) handler;
1240 return vm_to_proc(block_code);
1243 else if (blockiseq !=
NULL) {
1246 return VM_BH_FROM_ISEQ_BLOCK(captured);