pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:10123:       push_type(PIKE_T_UNKNOWN);       INIT_CALL_STATE(cs);       do {    struct pike_type *cont;       if (!b || b->type == T_MANY ||    (b->car && (b->car->flags & PT_FLAG_VOIDABLE))) { -  struct pike_type *tmp = new_get_return_type(a, 0); +  struct pike_type *tmp = new_get_return_type(a, &cs, 0); +     if (tmp) {    push_finished_type(tmp);    push_type(T_OR);       free_type(tmp);    }       if (!b || !b->car ||    ((b->type == T_MANY) && (b->car == void_type_string))) {    break;
pike.git/src/pike_types.cmod:10387:    p = id_to_program(CDR_TO_INT(t));       comefrom_int_index:    if(p && n)    {    INT32 i;    if(n->token == F_ARROW)    {    if((i=FIND_LFUN(p,LFUN_ARROW))!=-1)    { +  struct pike_type *ret = NULL;    struct call_state cs; -  +     INIT_CALL_STATE(cs);    add_ref(tmp = ID_FROM_INT(p, i)->type);    tmp = new_check_call(lfun_strings[LFUN_ARROW], tmp, CDR(n), &cs, 0); -  FREE_CALL_STATE(cs); +     if (tmp) { -  struct pike_type *ret = new_get_return_type(tmp, 0); +  ret = new_get_return_type(tmp, &cs, 0);    free_type(tmp); -  if (ret) return ret; +     } -  +  FREE_CALL_STATE(cs);    -  +  if (ret) return ret; +     /* Invalid type for lfun::`->(). */    add_ref(mixed_type_string);    return mixed_type_string;    }    }else{    if((i=FIND_LFUN(p,LFUN_INDEX)) != -1)    { -  +  struct pike_type *ret = NULL;    struct call_state cs; -  +     INIT_CALL_STATE(cs);    add_ref(tmp = ID_FROM_INT(p, i)->type);    tmp = new_check_call(lfun_strings[LFUN_INDEX], tmp, CDR(n), &cs, 0); -  FREE_CALL_STATE(cs); +     if (tmp) { -  struct pike_type *ret = new_get_return_type(tmp, 0); +  ret = new_get_return_type(tmp, &cs, 0);    free_type(tmp); -  if (ret) return ret; +     } -  +  FREE_CALL_STATE(cs);    -  +  if (ret) return ret;    /* Invalid type for lfun::`[](). */    add_ref(mixed_type_string);    return mixed_type_string;    }    }    if(CDR(n)->token == F_CONSTANT && TYPEOF(CDR(n)->u.sval) == T_STRING)    {    i = find_shared_string_identifier(CDR(n)->u.sval.u.string, p);    if(i==-1)    {
pike.git/src/pike_types.cmod:12007:    tmp = expand_transitive(fun_type, a_markers, 0);    res = lower_new_check_call(tmp, arg_type, flags,    cs, sval CHECK_CALL_ARGS);    free_type(tmp);   #else    /* There are two cases here; arg_type can belong to either    * fun_type->car, or (if fun_type->car can return here) the    * second argument to fun_type->cdr (or both).    */    if (fun_type->car) { -  tmp = new_get_return_type(fun_type->car, 0); +  tmp = new_get_return_type(fun_type->car, cs, 0);    } else { -  tmp = new_get_return_type(fun_type->cdr, 0); +  tmp = new_get_return_type(fun_type->cdr, cs, 0);    }    if (tmp) {    tmp2 = low_new_check_call(fun_type->cdr, tmp, 0, cs, NULL);    free_type(tmp);    tmp = NULL;    if (tmp2) {    /* tmp is a valid argument to fun_type->cdr,    * so check if arg_type is also valid. */    tmp = lower_new_check_call(tmp2, arg_type, flags,    cs, sval CHECK_CALL_ARGS);
pike.git/src/pike_types.cmod:12481:    }    return tmp;   }      /**    * Return the return type for the function type fun_type, if    * no further arguments are passed.    *    * Returns NULL if more arguments are required.    * -  * Returns a the type of the return value otherwise. +  * Returns the type of the return value otherwise.    */   struct pike_type *new_get_return_type(struct pike_type *fun_type, -  +  struct call_state *cs,    INT32 flags)   {    struct compilation *c = MAYBE_THIS_COMPILATION;    struct pike_type *res = NULL;    struct pike_type *tmp;    struct pike_type *tmp2;    INT32 array_cnt = 0;      #ifdef PIKE_DEBUG    if (l_flag>2) {
pike.git/src/pike_types.cmod:12516:    }       switch(fun_type?(fun_type->type & PIKE_T_MASK):PIKE_T_UNKNOWN) {    case PIKE_T_SCOPE:    case T_ASSIGN:    case PIKE_T_NAME:    fun_type = fun_type->cdr;    goto loop;       case PIKE_T_ATTRIBUTE: -  tmp = new_get_return_type(fun_type->cdr, flags); +  tmp = new_get_return_type(fun_type->cdr, cs, flags);    if (!tmp) break;    if (c) {    ref_push_string((struct pike_string *)fun_type->car);    ref_push_type_value(fun_type->cdr);    safe_apply_current2(PC_APPLY_TYPE_ATTRIBUTE_FUN_NUM, 2,    "apply_type_attribute");    if ((TYPEOF(Pike_sp[-1]) == T_INT) &&    (SUBTYPEOF(Pike_sp[-1]) == NUMBER_NUMBER) &&    (!Pike_sp[-1].u.integer)) {    free_type(tmp);
pike.git/src/pike_types.cmod:12544:    push_type_attribute((struct pike_string *)fun_type->car);    res = pop_unfinished_type();    free_type(tmp);    break;       case PIKE_T_RING:    fun_type = fun_type->car;    goto loop;       case T_OR: -  if (!(res = new_get_return_type(fun_type->car, flags))) { +  if (!(res = new_get_return_type(fun_type->car, cs, flags))) {    fun_type = fun_type->cdr;    goto loop;    } -  if (!(tmp = new_get_return_type(fun_type->cdr, flags))) { +  if (!(tmp = new_get_return_type(fun_type->cdr, cs, flags))) {    break;    }    if ((res == void_type_string) || (tmp == void_type_string)) {    /* Note: Promote void to zero in the return value    * when there's another non-void result.    */    if (tmp == void_type_string) {    /* Keep res as is. */    free_type(tmp);    } else {    free_type(res);    res = tmp;    }    break;    }    res = or_pike_types(tmp2 = res, tmp, 1);    free_type(tmp2);    free_type(tmp);    break;    case T_AND: -  if (!(res = new_get_return_type(fun_type->car, flags))) { +  if (!(res = new_get_return_type(fun_type->car, cs, flags))) {    break;    } -  if (!(tmp = new_get_return_type(fun_type->cdr, flags))) { +  if (!(tmp = new_get_return_type(fun_type->cdr, cs, flags))) {    free_type(res);    res = NULL;    break;    }    res = and_pike_types(tmp2 = res, tmp);    free_type(tmp);    free_type(tmp2);    break;    case T_NOT: -  if (!(res = new_get_return_type(fun_type->car, flags))) { +  if (!(res = new_get_return_type(fun_type->car, cs, flags))) {    copy_pike_type(res, mixed_type_string);    } else if (res->type == T_NOT) {    tmp = res;    copy_pike_type(res, tmp->car);    free_type(tmp);    } else if ((res == mixed_type_string) || (res == any_type_string)) {    free_type(res);    return NULL;    } else {    type_stack_mark();
pike.git/src/pike_types.cmod:12613:    case PIKE_T_PROGRAM:    tmp = low_object_lfun_type(fun_type->car, LFUN_CREATE);    if (!tmp) {    /* No create(). */    add_ref(fun_type->car);    res = fun_type->car;    break;    } else {    fun_type = zzap_function_return(tmp, fun_type->car);    } -  res = new_get_return_type(fun_type, flags); +  res = new_get_return_type(fun_type, cs, flags);    free_type(fun_type);    break;    case PIKE_T_OBJECT:    fun_type = low_object_lfun_type(fun_type, LFUN_CALL);    if (fun_type) goto loop;    /* FIXME: Multiple cases:    * Untyped object.    * Failed to lookup program id.    * Program does not have the lfun `()().    */
pike.git/src/pike_types.cmod:12674:    */    copy_pike_type(res, mixed_type_string);    }    break;       case PIKE_T_OPERATOR:    tmp = apply_type_operator(fun_type->type, fun_type->car, fun_type->cdr);    if (!tmp) {    return NULL;    } -  res = new_get_return_type(tmp, flags); +  res = new_get_return_type(tmp, cs, flags);    free_type(tmp);    break;       case PIKE_T_TRANSITIVE:    /* NB: Not 100% correct, but good enough for most purposes. */    if (fun_type->car) {    fun_type = fun_type->car;    } else {    fun_type = fun_type->cdr;    }
pike.git/src/pike_types.cmod:13925:    return NULL;   }      struct pike_type *apply_type_operator(enum PIKE_TYPE op,    struct pike_type *arg1,    struct pike_type *arg2)   {    struct pike_type *res = NULL;    switch(op) {    case PIKE_T_GET_RETURN: -  res = new_get_return_type(arg1, 0); +  { +  struct call_state cs; +  INIT_CALL_STATE(cs); +  res = new_get_return_type(arg1, &cs, 0); +  FREE_CALL_STATE(cs); +  }    break;    case PIKE_T_APPLY:    {    struct call_state cs;    INIT_CALL_STATE(cs);    res = low_new_check_call(arg1, arg2, 0, &cs, NULL);    FREE_CALL_STATE(cs);    }    break;    case PIKE_T_FIND_LFUN: