pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:4524:    return pop_unfinished_type();    case PIKE_T_ATTRIBUTE:    tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);    if (!tmp) return NULL;    type_stack_mark();    push_finished_type(tmp);    push_type_attribute((struct pike_string *)(a->car));    free_type(tmp);    return pop_unfinished_type();    case T_SCOPE: -  tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags); +  tmp = low_type_binop(op, a->cdr, b, remap, +  aflags | PT_FLAG_CMP_INSEPARABLE, bflags, +  remap_flags);    if (!tmp) return NULL;    type_stack_mark();    push_finished_type(tmp);    push_scope_type(CAR_TO_INT(a));    free_type(tmp);    return pop_unfinished_type();    }    switch(b->type) {    case PIKE_T_NAME:    tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
pike.git/src/pike_types.cmod:4550:    return pop_unfinished_type();    case PIKE_T_ATTRIBUTE:    tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);    if (!tmp) return NULL;    type_stack_mark();    push_finished_type(tmp);    push_type_attribute((struct pike_string *)(b->car));    free_type(tmp);    return pop_unfinished_type();    case T_SCOPE: -  tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags); +  tmp = low_type_binop(op, a, b->cdr, remap, +  aflags, bflags | PT_FLAG_CMP_INSEPARABLE, +  remap_flags);    if (!tmp) return NULL;    type_stack_mark();    push_finished_type(tmp);    push_scope_type(CAR_TO_INT(b));    free_type(tmp);    return pop_unfinished_type();    }    -  +  if (remap_flags & PT_FLAG_REMAP_TRACE) { +  fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); +  } +     /* Check consolidated types. */    switch(a->type) {    case T_OR:    /* (a1 | a2) op b <==> (a1 op b) | (a2 op b) */    tmp = low_type_binop(op, a->car, b, remap, aflags, bflags, remap_flags);    tmp2 = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags); -  +  if ((op & PT_BINOP_NOT_A) || (aflags & PT_FLAG_CMP_INSEPARABLE)) { +  if (!tmp2) { +  free_type(tmp); +  return NULL; +  } +  if (!tmp) { +  free_type(tmp2); +  return NULL; +  } +  } else {    if (!tmp2) return tmp;    if (!tmp) return tmp2; -  +  }       type_stack_mark();    push_finished_type(tmp);    push_finished_type(tmp2);    push_reverse_type(T_OR);    free_type(tmp);    free_type(tmp2);    return pop_unfinished_type();       case T_AND:
pike.git/src/pike_types.cmod:4890:    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();    }    }    break;       case PT_BINOP_MINUS:    /* Subtraction (A - B)    * +  * Old approach (broken, separable argument types): +  *    * The result is the subset of function A where at least one    * of the arguments or the return type differs from function B.    *    * T_FUNCTION(A, X) - T_FUNCTION(B, Y) ==    * T_OR(T_FUNCTION(A - B, X), T_FUNCTION(A, X - Y))    *    * T_FUNCTION(A, X) - T_MANY(T_VOID, Y) ==    * T_OR(T_FUNCTION(A - T_VOID, X),    * T_MANY(T_VOID, X* - Y))    *
pike.git/src/pike_types.cmod:4947:   #if 0    fprintf(stderr, "arg_check(op: 0x%x, ", op);    simple_describe_type(ai);    fprintf(stderr, " (%d), ", avoidable);    simple_describe_type(bi);    fprintf(stderr, " (%d))\n\n", bvoidable);   #endif       /* FIXME: Use implicit nullable only for legacy types. */    tmp = low_type_binop(op, ai->car, bi->car, remap, -  avoidable | PT_FLAG_CMP_NULLABLE, -  bvoidable | PT_FLAG_CMP_NULLABLE, +  avoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE, +  bvoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE,    remap_flags);       /* Advance to the next argument. */    if (ai->type == T_FUNCTION) {    ai = ai->cdr;    }    if (bi->type == T_FUNCTION) {    bi = bi->cdr;    }    if ((ai->type != T_FUNCTION) && (ai->type != T_MANY)) {
pike.git/src/pike_types.cmod:4986:       if (avoidable && bvoidable) {    /* FIXME: What if tmp only differs due to remapping? */    if (tmp && tmp->type == T_VOID) {    free_type(tmp);    tmp = NULL;    }    if (tmp != a->car) {    if (!tmp) {    tmp = low_type_binop(op, a->cdr, b->cdr, remap, -  PT_FLAG_CMP_VOIDABLE, -  0, remap_flags); +  PT_FLAG_CMP_VOIDABLE | +  (aflags & PT_FLAG_CMP_INSEPARABLE), +  0 | +  (bflags & PT_FLAG_CMP_INSEPARABLE), +  remap_flags);    if (tmp) {    push_finished_type(tmp);    push_type(T_VOID);    push_type(T_MANY);    free_type(tmp);    return pop_unfinished_type();    }    pop_stack_mark();    return NULL;    }
pike.git/src/pike_types.cmod:5028:    return pop_unfinished_type();    }       /* Time to check the return types. */       if (!aret) aret = ai->cdr;    if (!bret) bret = bi->cdr;       /* NB: Ignore the return type if matching against void. */    tmp = low_type_binop(op, aret, bret, remap, -  PT_FLAG_CMP_VOIDABLE, -  0, remap_flags); +  PT_FLAG_CMP_VOIDABLE | +  (aflags & PT_FLAG_CMP_INSEPARABLE), +  0 | +  (bflags & PT_FLAG_CMP_INSEPARABLE), +  remap_flags);       if (remap_flags & PT_FLAG_REMAP_TRACE) {    fprintf(stderr, "ret tmp: ");    simple_describe_type(tmp);    fprintf(stderr, "\n");    }       if (!tmp) goto function_fail;       push_finished_type(tmp);
pike.git/src/pike_types.cmod:5082:    push_type(T_FUNCTION);    free_type(tmp);    }    nargs = peek_stack_mark();    if (!nargs) {    pop_stack_mark();    return NULL;    }    while (nargs-- > 1) push_type(T_OR);    return pop_unfinished_type(); +     default:    /* Fall back to complex_function below. */    break;    }       complex_function:       nargs = peek_stack_mark();    if (op != PT_BINOP_AND) {    nargs = 0;
pike.git/src/pike_types.cmod:5285:    }       if (a->type != T_VOID) {    if (b->type == T_MIXED) {    switch(op & PT_BINOP_B) {    case 0:    return NULL;    case PT_BINOP_AND:    return remap_markers(a, NULL, remap, remap_flags);    case PT_BINOP_INVERSE_MINUS: +  if (bflags & PT_FLAG_CMP_INSEPARABLE) { +  return NULL; +  }    type_stack_mark();    push_remap_markers(a, NULL, remap, remap_flags);    push_type(T_NOT);    return pop_unfinished_type();    default:    add_ref(b);    return b;    }    }    }    if (b->type != T_VOID) {    if (a->type == T_MIXED) {    switch(op & PT_BINOP_A) {    case 0:    return NULL;    case PT_BINOP_AND:    return remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    case PT_BINOP_MINUS: -  +  if (aflags & PT_FLAG_CMP_INSEPARABLE) { +  return NULL; +  }    type_stack_mark();    push_remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    push_type(T_NOT);    return pop_unfinished_type();    default:    add_ref(a);    return a;    }    }
pike.git/src/pike_types.cmod:5362:    case PT_BINOP_ALL:    push_type(T_MIXED);    break;       case PT_BINOP_MINUS:    case PT_BINOP_A:    push_remap_markers(a, NULL, remap, remap_flags);    break;    case PT_BINOP_NOT_A:    case PT_BINOP_NOT_A_OR_B: +  if (aflags & PT_FLAG_CMP_INSEPARABLE) { +  pop_stack_mark(); +  return NULL; +  }    push_remap_markers(a, NULL, remap, remap_flags);    push_type(T_NOT);    break;       case PT_BINOP_INVERSE_MINUS:    case PT_BINOP_B:    push_remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    break;    case PT_BINOP_NOT_B:    case PT_BINOP_A_OR_NOT_B: -  +  if (bflags & PT_FLAG_CMP_INSEPARABLE) { +  pop_stack_mark(); +  return NULL; +  }    push_remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    push_type(T_NOT);    break;       case PT_BINOP_OR:    case PT_BINOP_XOR:    push_remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    push_remap_markers(a, NULL, remap, remap_flags);    push_type(T_OR);    break;    case PT_BINOP_NOR:    case PT_BINOP_XNOR: -  +  if ((aflags | bflags) & PT_FLAG_CMP_INSEPARABLE) { +  pop_stack_mark(); +  return NULL; +  }    push_remap_markers(b, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    push_remap_markers(a, NULL, remap, remap_flags);    push_type(T_OR);    push_type(T_NOT);    break;    }    return pop_unfinished_type();    }   
pike.git/src/pike_types.cmod:5546:    } else {    push_int_type(bound, MAX_INT32);    }    }       nbounds = peek_stack_mark();    if (!nbounds) {    pop_stack_mark();    return NULL;    } +  +  if ((op == PT_BINOP_MINUS) && (aflags & PT_FLAG_CMP_INSEPARABLE)) { +  if ((nbounds != 1) || (peek_type_stack() != a)) { +  compiler_discard_type(); +  return NULL; +  } +  } +     /* NB: Loop starts at 1! */    for (i = 1; i < nbounds; i++) {    push_type(T_OR);    }    return pop_unfinished_type();    }       case T_ARRAY:    case T_MAPPING:    case T_STRING: -  +  /* FIXME: Handle PT_FLAG_CMP_INSEPARABLE. */    tmp = low_type_binop(op, a->car, b->car, remap,    0, 0, remap_flags);    if (!tmp && (op == PT_BINOP_AND)) return NULL;    if (a->type == T_STRING) {    tmp2 = low_type_binop(op, a->cdr, b->cdr, remap,    0, 0, remap_flags);    } else {    /* Mappings may always result in UNDEFINED on indexing.    * Arrays are typically initialized to all zeroes.    */
pike.git/src/pike_types.cmod:5607:    push_finished_type(tmp2);    push_reverse_type(a->type);    free_type(tmp);    free_type(tmp2);    }    return pop_unfinished_type();       case T_MULTISET:    case T_PROGRAM:    case T_TYPE: +  /* FIXME: Handle PT_FLAG_CMP_INSEPARABLE. */    tmp = low_type_binop(op, a->car, b->car, remap,    0, 0, remap_flags);    if (!tmp) return NULL;    type_stack_mark();    push_finished_type(tmp);    push_type(a->type);    free_type(tmp);    return pop_unfinished_type();       case T_OBJECT: -  +  /* FIXME: Handle PT_FLAG_CMP_INSEPARABLE. */    switch(op) {    case PT_BINOP_AND:    if (!a->cdr) {    add_ref(b);    return b;    }    if (!b->cdr) {    add_ref(a);    return a;    }