pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:4469:    return ret;       default:    /* Make the C-compiler happy. */   #ifdef PIKE_DEBUG    Pike_fatal("Unsupported binary type operation: 0x%02x\n", op);   #endif    break;    }    -  if (!a || !b) { -  if (a) { -  if (op & PT_BINOP_MINUS) { -  add_ref(a); -  return a; -  } -  } else if (b) { -  if (op & PT_BINOP_INVERSE_MINUS) { -  add_ref(b); -  return b; -  } -  } else if (op & PT_BINOP_NOR) { -  type_stack_mark(); -  push_type(T_MIXED); -  push_type(T_VOID); -  push_type(T_OR); -  return pop_unfinished_type(); -  } -  return NULL; -  } -  +     full_loop:    if (a == b) {    if (op & PT_BINOP_AND) {    /* FIXME: Perform masking of remap_flags here. */    return remap_markers(a, NULL, remap,    remap_flags | PT_FLAG_REMAP_BOTH_MARKERS_AND);    } else {    return NULL;    }    }       /* First check for markers. */ -  switch(a->type) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);    tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);    if (tmp) {    type_stack_mark();    push_finished_type(tmp);    push_assign_type(marker);    free_type(tmp);    return pop_unfinished_type();    }    free_marker(remap, CAR_TO_INT(a), remap_flags);    return NULL;    }    } -  switch(b->type) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker = alloc_remap_marker(remap, CAR_TO_INT(b),    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);    if (tmp) {    type_stack_mark();    push_finished_type(tmp);    push_assign_type(marker);    free_type(tmp);    return pop_unfinished_type();    }       free_marker(remap, CAR_TO_INT(b),    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    return NULL;    }    }       /* Attributes and names. */ -  switch(a->type) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    case PIKE_T_NAME:    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_name((struct pike_string *)(a->car));    free_type(tmp);    return pop_unfinished_type();    case PIKE_T_ATTRIBUTE:    tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);
pike.git/src/pike_types.cmod:4567:    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) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case PIKE_T_NAME:    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_name((struct pike_string *)(b->car));    free_type(tmp);    return pop_unfinished_type();    case PIKE_T_ATTRIBUTE:    tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);
pike.git/src/pike_types.cmod:4601:    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) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    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) {
pike.git/src/pike_types.cmod:4673:    return pop_unfinished_type();    case T_NOT:    /* Rotate the opcode 2 bits.    *    * This converts A to ~A and vice versa.    */    op = ((op << 2) | (op >> 2)) & PT_BINOP_ALL;    return low_type_binop(op, a->car, b,    remap, aflags, bflags, remap_flags);    } -  switch(b->type) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case T_OR:    if ((op == PT_BINOP_MINUS) || (op == PT_BINOP_OR)) {    /* Special case to avoid excessively complicated expressions    * in the result.    *    * A - (B | C) == (A - B) - C    * rather than    * A - (B | C) == (A - B) & (A - C)    *    * A | (B | C) == (A | B) | C
pike.git/src/pike_types.cmod:4775:    case T_NOT:    /* Swap the bits of the opcode pairwise.    *    * This converts B to ~B and vice versa.    */    op = (((op & PT_BINOP_B) << 1) | ((op >> 1) & PT_BINOP_B)) & PT_BINOP_ALL;    return low_type_binop(op, a, b->car,    remap, aflags, bflags, remap_flags);    }    +  /* +  * NB: At this point a and b are either NULL or a basic type. +  */ +  +  /* Handle a or b being NULL. */ +  /* NB: We know that a != b due to an earlier test. */ +  if (!a) { +  if (op & PT_BINOP_INVERSE_MINUS) { +  if (!((b == void_type_string) && (aflags & PT_FLAG_CMP_VOIDABLE)) && +  !((b == zero_type_string) && (aflags & PT_FLAG_CMP_NULLABLE))) { +  add_ref(b); +  return b; +  } +  } +  return NULL; +  } +  if (!b) { +  if (op & PT_BINOP_MINUS) { +  if (!((a == void_type_string) && (bflags & PT_FLAG_CMP_VOIDABLE)) && +  !((a == zero_type_string) && (bflags & PT_FLAG_CMP_NULLABLE))) { +  add_ref(a); +  return a; +  } +  } +  return NULL; +  } +     /* Check implicit casting. */    loop:    switch(TWOT(a->type & PIKE_T_MASK, b->type & PIKE_T_MASK)) {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_PROGRAM, T_MANY):    aret = a->car;    a = low_object_lfun_type(aret, LFUN_CREATE);    if (!a) {    a = void_function_type_string;    }