pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:12804:      /* NOTE: fun_type loses a reference. */   struct pike_type *check_splice_call(struct pike_string *fun_name,    struct pike_type *fun_type,    INT32 argno,    struct pike_type *args_type,    struct svalue *sval,    INT32 flags)   {    struct compilation *c = THIS_COMPILATION; -  struct pike_type *tmp = NULL; +     struct pike_type *res = NULL; -  struct pike_type *prev = fun_type; +     struct pike_type *arg_type = index_type(args_type, int_type_string, NULL);    struct pike_type *ind_type = key_type(args_type, NULL); -  int cnt = 256; +  INT_TYPE ind_range[2] = { 256, 0 }; +  int min_cnt = 0; +  int max_cnt = 256; +  int cnt = 0;    /* This argument can expand to anything between zero and MAX_ARGS args. */    -  copy_pike_type(res, fun_type); +  if (get_int_type_range(ind_type, ind_range)) { +  min_cnt = ind_range[0]; +  max_cnt = ind_range[1];    -  /* Loop until we get a stable fun_type, or it's an invalid argument. */ -  while ((fun_type = low_new_check_call(debug_malloc_pass(prev), -  debug_malloc_pass(arg_type), -  flags|CALL_NOT_LAST_ARG, sval)) && -  (fun_type != prev) && --cnt) { +  if (max_cnt < min_cnt) { +  /* Mixed or similar range. */ +  min_cnt = 0; +  max_cnt = 256; +  } +  if (min_cnt < 0) min_cnt = 0; +  if (max_cnt > 256) max_cnt = 256; +  }      #ifdef PIKE_DEBUG    if (l_flag>4) { -  fprintf(stderr, "\n sub_result_type: "); +  fprintf(stderr, "check_splice_call(\"%s\", ", fun_name->str);    simple_describe_type(fun_type); -  +  fprintf(stderr, ",\n %d, ", argno); +  simple_describe_type(args_type); +  fprintf(stderr, ",\n %p, 0x%04x)", sval, flags); +  fprintf(stderr, "\n range: [%d..%d] ", min_cnt, max_cnt); +  simple_describe_type(ind_type);    }   #endif /* PIKE_DEBUG */    -  res = dmalloc_touch(struct pike_type *, -  or_pike_types(debug_malloc_pass(tmp = res), -  debug_malloc_pass(fun_type), 1)); +  /* Loop until we get a stable fun_type, or it's an invalid argument. */ +  for (cnt = 0;; cnt++) { +  struct pike_type *prev = NULL; +  +  if (cnt >= min_cnt) { +  res = or_pike_types(prev = res, fun_type, 1); +  free_type(prev); +    #ifdef PIKE_DEBUG    if (l_flag>4) {    fprintf(stderr, "\n joined_type: ");    simple_describe_type(res);    }   #endif /* PIKE_DEBUG */    -  if ((res == tmp) || (res == fun_type)) { -  free_type(tmp); +  if ((res == prev) || (prev && (res == fun_type))) { +  /* Stable result. */    break;    } -  free_type(tmp); +  }    -  +  if (cnt >= max_cnt) break; +  +  fun_type = low_new_check_call(prev = fun_type, arg_type, +  flags | CALL_NOT_LAST_ARG, sval);    free_type(prev); -  prev = fun_type; +  + #ifdef PIKE_DEBUG +  if (l_flag>4) { +  fprintf(stderr, "\n sub_result_type: "); +  simple_describe_type(fun_type);    } -  free_type(prev); -  if (fun_type) { + #endif /* PIKE_DEBUG */ +  +  if (!fun_type || (fun_type == prev)) { +  /* Stable result. */ +  break; +  } +  } +  +  if (fun_type || (cnt >= max_cnt)) {    /* Max args reached or stable type. */    free_type(fun_type);    } else if (!(flags & CALL_INHIBIT_WARNINGS)) {    /* The splice values are invalid for later arguments. */ -  if (cnt == 256) { +  if (!cnt && max_cnt) {    yywarning("In argument %d to %S: The @-operator argument must be an empty array.",    argno, fun_name);    } else if (c->lex.pragmas & ID_STRICT_TYPES) {    yywarning("In argument %d to %S: The @-operator argument has a max length of %d.", -  argno, fun_name, 256-cnt); +  argno, fun_name, cnt);    }    }       free_type(ind_type);    free_type(arg_type);    -  + #ifdef PIKE_DEBUG +  if (l_flag>4) { +  fprintf(stderr, "\ncheck_splice_call(...) ==> "); +  simple_describe_type(res); +  fprintf(stderr, "\n"); +  } + #endif /* PIKE_DEBUG */ +     return res;   }      /* NOTE: fun_type loses a reference. */   static struct pike_type *new_check_call_arg(struct pike_string *fun_name,    struct pike_type *fun_type,    node *args, INT32 *argno,    INT32 flags)   {    struct compilation *c = THIS_COMPILATION;