pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:3973:   #endif   }            /******/      struct remap_state {    unsigned char map[0x20];    unsigned INT32 allocated; -  struct mapping *markers; +  struct mapping *markers[2];   };      #ifdef PIKE_NULL_IS_SPECIAL   #define INIT_REMAP_STATE(REMAP) do { \    memset(&REMAP, 0, sizeof(struct remap_state)); \ -  REMAP.markers = NULL; \ +  REMAP.markers[0] = NULL; \ +  REMAP.markers[1] = NULL; \    } while(0)   #else   #define INIT_REMAP_STATE(REMAP) do { \    memset(&REMAP, 0, sizeof(struct remap_state)); \    } while(0)   #endif   static inline void exit_remap_state(struct remap_state *remap)   { -  if (remap && remap->markers) { -  free_mapping(remap->markers); -  remap->markers = NULL; +  if (remap && remap->markers[0]) { +  free_mapping(remap->markers[0]); +  remap->markers[0] = NULL;    } -  +  if (remap && remap->markers[1]) { +  free_mapping(remap->markers[1]); +  remap->markers[1] = NULL;    } -  + }   #define EXIT_REMAP_STATE(REMAP) exit_remap_state(&REMAP)      static int alloc_remap_marker(struct remap_state *remap, int marker,    enum pt_remap_flags flags)   {    int ret;       marker = marker & 0x0f;       if (!remap || (flags & PT_FLAG_REMAP_INHIBIT)) return '0' | marker;
pike.git/src/pike_types.cmod:4062:    marker &= 0x0f;       if (flags & PT_FLAG_REMAP_SWAP_MARKERS) marker |= 0x10;       if (!(m = remap->map[marker])) return;       remap->map[marker] = 0;    remap->allocated &= ~(1 << (m & 0x0f));   }    - static struct pike_type *lookup_marker(struct remap_state *remap, int marker) + static int lookup_marker(struct remap_state *remap, int marker, +  enum pt_remap_flags flags, +  struct pike_type **result_type)   { -  struct svalue key, *val; +  struct svalue key, *val = NULL; +  int marker_set = !!(flags & PT_FLAG_REMAP_SWAP_MARKERS);    -  if (!remap || !remap->markers || !marker) return NULL; +  if (!remap || !remap->markers[marker_set] || !marker) { +  return 0; +  }       SET_SVAL(key, T_INT, NUMBER_NUMBER, integer, marker);    -  val = low_mapping_lookup(remap->markers, &key); -  if (!val) return NULL; +  val = low_mapping_lookup(remap->markers[marker_set], &key); +  if (!val) return 0;       if ((TYPEOF(*val) == PIKE_T_TYPE) && val->u.type) {    add_ref(val->u.type); -  return val->u.type; +  *result_type = val->u.type; +  } else { +  *result_type = NULL;    } -  return NULL; +  return 1;   } - #define lookup_marker(REMAP, M) ((struct pike_type *)debug_malloc_pass(lookup_marker(REMAP, M))) + #define lookup_marker(REMAP, M, F, RES) (lookup_marker(REMAP, M, F, RES)?(debug_malloc_pass(*(RES)),1):0)      static void store_marker(struct remap_state *remap, int marker, -  struct pike_type *value) +  struct pike_type *value, enum pt_remap_flags flags)   {    struct svalue key, val; -  +  int marker_set = !!(flags & PT_FLAG_REMAP_SWAP_MARKERS);       if (!remap || !marker) return;    -  if (!remap->markers) { -  remap->markers = allocate_mapping(10); +  if (!remap->markers[marker_set]) { +  remap->markers[marker_set] = allocate_mapping(10);    }       SET_SVAL(key, T_INT, NUMBER_NUMBER, integer, marker);    if (value) {    SET_SVAL(val, T_TYPE, 0, type, value);    } else {    SET_SVAL(val, T_INT, NUMBER_NUMBER, integer, 0);    } -  mapping_insert(remap->markers, &key, &val); +  mapping_insert(remap->markers[marker_set], &key, &val);   } - #define store_marker(REMAP, M, T) store_marker(REMAP, M, debug_malloc_pass(T)) + #define store_marker(REMAP, M, T, F) store_marker(REMAP, M, debug_malloc_pass(T), F)      /**    * Copy marker assignments from remap->markers to    * their corresponding T_ASSIGN nodes (aka backpatch).    *    * Leave the result on the type stack.    */   static void push_and_fixup_markers(struct pike_type *t, -  struct remap_state *remap) +  struct remap_state *remap, +  enum pt_remap_flags flags)   {    if (!t || !(t->flags & PT_FLAG_ASSIGN) || !remap || !remap->markers) {    /* Type t does not contain any marker assignments,    * or the remap state has no markers set.    */    push_finished_type(t);    return;    }    /* NB: Many of the cases in the switch below are unreached    * as they never contain a T_ASSIGN and thus are    * handled by the PT_FLAG_ASSIGN test above.    */    switch(t->type & (0x8000 | PIKE_T_MASK)) {    case T_ASSIGN:    {    int marker = '0' + CAR_TO_INT(t); -  struct pike_type *t2 = lookup_marker(remap, marker | 0x100); +  struct pike_type *t2 = NULL; +  if (lookup_marker(remap, marker | 0x100, flags, &t2)) {    push_finished_type(t2); -  push_assign_type(marker); +     free_type(t2); -  +  } else { +  push_finished_type(t->cdr);    } -  +  push_assign_type(marker); +  }    break;       case PIKE_T_NAME: -  push_and_fixup_markers(t->cdr, remap); +  push_and_fixup_markers(t->cdr, remap, flags);    push_type_name((struct pike_string *)(t->car));    break;       case PIKE_T_ATTRIBUTE: -  push_and_fixup_markers(t->cdr, remap); +  push_and_fixup_markers(t->cdr, remap, flags);    push_type_attribute((struct pike_string *)(t->car));    break;       case T_SCOPE: -  push_and_fixup_markers(t->cdr, remap); +  push_and_fixup_markers(t->cdr, remap, flags);    push_scope_type(CAR_TO_INT(t));    break;       case T_MULTISET:    case T_NOT:    case T_TYPE:    case PIKE_T_AUTO:    case T_PROGRAM:    /* t->car is node. */ -  push_and_fixup_markers(t->car, remap); +  push_and_fixup_markers(t->car, remap, flags);    push_type(t->type);    break;       case PIKE_T_OPERATOR:    push_finished_type(t->car);    push_type_operator(t->type, t->cdr);    break;       case T_FUNCTION:    case T_MANY:    case PIKE_T_RING:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case T_ARRAY:    case T_STRING:    case PIKE_T_TRANSITIVE:    case PIKE_T_OPERATOR | 0x8000:    /* t->car and t->cdr are nodes. */ -  push_and_fixup_markers(t->cdr, remap); -  push_and_fixup_markers(t->car, remap); +  push_and_fixup_markers(t->cdr, remap, flags); +  push_and_fixup_markers(t->car, remap, flags);    push_type(t->type);    break;       case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    case T_MIXED:    case T_VOID:    case T_ZERO:    case T_FLOAT:    case T_INT:
pike.git/src/pike_types.cmod:4220:       switch(t->type & PIKE_T_MASK) {    case T_ASSIGN:    {    int marker = alloc_remap_marker(remap, CAR_TO_INT(t), flags);       if (!(flags & PT_FLAG_REMAP_EVAL_MARKERS)) {    push_remap_markers(t->cdr, remap, flags);    push_assign_type(marker);    } else { -  struct pike_type *old = lookup_marker(remap, marker); +  struct pike_type *old = NULL;    struct pike_type *new = t->cdr; -  +  lookup_marker(remap, marker, flags, &old);    if (new) {    if (old) {    new = or_pike_types(old, new, 0);    } else {    add_ref(new);    } -  store_marker(remap, marker, new); +  store_marker(remap, marker, new, flags);    free_type(new);    }    free_type(old);    push_remap_markers(t->cdr, remap, flags);    }       if (flags & PT_FLAG_REMAP_BOTH_MARKERS) {    marker = alloc_remap_marker(remap, CAR_TO_INT(t),    flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       if (!(flags & PT_FLAG_REMAP_EVAL_MARKERS)) {    push_assign_type(marker);    } else { -  struct pike_type *old = lookup_marker(remap, marker); +  struct pike_type *old = NULL;    struct pike_type *new = t->cdr; -  +  lookup_marker(remap, marker, +  flags ^ PT_FLAG_REMAP_SWAP_MARKERS, &old);    if (old) {    new = or_pike_types(old, new, 0);    } else {    add_ref(new);    } -  store_marker(remap, marker, new); +  store_marker(remap, marker, new, flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    free_type(new);    free_type(old); -  push_remap_markers(t->cdr, remap, flags); +  push_remap_markers(t->cdr, remap, flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       switch(flags & PT_FLAG_REMAP_BOTH_MARKERS_MASK) {    case PT_FLAG_REMAP_BOTH_MARKERS_AND:    push_type(T_AND);    break;    case PT_FLAG_REMAP_BOTH_MARKERS_OR:    push_type(T_OR);    break;    default:    Pike_fatal("Unsupported marker joining method.\n");
pike.git/src/pike_types.cmod:4274:    }    }    }    break;    }       case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    {    int marker = remap_marker(remap, t->type, flags); -  struct pike_type *value = lookup_marker(remap, marker); +  struct pike_type *value = NULL;    -  if (value) { +  if (lookup_marker(remap, marker, flags, &value)) {    push_remap_markers(value, remap, flags);    free_type(value);    if (marker && (flags & PT_FLAG_REMAP_KEEP_MARKERS)) {    push_type(marker);    push_type(T_OR);    }    } else if (flags & PT_FLAG_REMAP_EVAL_MARKERS) {    /* Marker without matching assign.    * NB: Not an error. Consider    *
pike.git/src/pike_types.cmod:4308:    /* FIXME: Improve error handling here. */    push_type(T_MIXED);    } else {    push_type(marker);    }    }       if (flags & PT_FLAG_REMAP_BOTH_MARKERS) {    marker = remap_marker(remap, t->type,    flags ^ PT_FLAG_REMAP_SWAP_MARKERS); -  value = lookup_marker(remap, marker); -  -  if (value) { -  push_remap_markers(value, remap, flags); +  value = NULL; +  if (lookup_marker(remap, marker, +  flags ^ PT_FLAG_REMAP_SWAP_MARKERS, &value)) { +  push_remap_markers(value, remap, flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    free_type(value);    } else if (flags & PT_FLAG_REMAP_EVAL_MARKERS) {    /* Marker without matching assign. */    /* FIXME: Report error? */    push_type(T_MIXED);    } else {       /* Remap the marker. */       if (!marker) {
pike.git/src/pike_types.cmod:4431:    */   static struct pike_type *remap_markers(struct pike_type *t,    struct remap_state *remap,    enum pt_remap_flags flags)   {    if (!t) return NULL;       if (flags & PT_FLAG_REMAP_TRACE) {    fprintf(stderr, "remap_markers(");    simple_describe_type(t); -  fprintf(stderr, ", "); -  simple_describe_mapping(remap->markers); -  fprintf(stderr, ", %p, 0x%02x)\n", remap, flags); +  fprintf(stderr, ", {"); +  simple_describe_mapping(remap?remap->markers[0]:NULL); +  simple_describe_mapping(remap?remap->markers[1]:NULL); +  fprintf(stderr, "}, %p, 0x%02x)\n", remap, flags);    }       type_stack_mark();    push_remap_markers(t, remap, flags);       if (flags & PT_FLAG_REMAP_TRACE) {    fprintf(stderr, "remap ==> ");    simple_describe_type(peek_type_stack());    fprintf(stderr, "\n");    }
pike.git/src/pike_types.cmod:4733:    /* First check for markers. */    switch(a?a->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker;    tmp = low_type_binop(PT_BINOP_AND, a->cdr, b, remap,    aflags, bflags, remap_flags);       marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);    /* Marker value */ -  store_marker(remap, marker, tmp); +  store_marker(remap, marker, tmp, remap_flags);       if (op != PT_BINOP_AND) {    if ((op == PT_BINOP_MINUS) && !tmp) {    tmp = a->cdr;    if (tmp) add_ref(tmp);    } else if ((op == PT_BINOP_MINUS) && (tmp == a->cdr)) {    free_type(tmp);    tmp = NULL;    } else {    free_type(tmp);    tmp = low_type_binop(op, a->cdr, b, remap,    aflags, bflags, remap_flags);    }    }       /* Value to backpatch. */ -  store_marker(remap, marker | 0x100, tmp); +  store_marker(remap, marker | 0x100, tmp, remap_flags);       if (!tmp) return NULL;       type_stack_mark();    push_finished_type(tmp);    push_assign_type(marker);    free_type(tmp);    return pop_unfinished_type();    }    }    switch(b?b->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker;    tmp = low_type_binop(PT_BINOP_AND, a, b->cdr, remap,    aflags, bflags, remap_flags);       marker = alloc_remap_marker(remap, CAR_TO_INT(b),    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    /* Marker value */ -  store_marker(remap, marker, tmp); +  store_marker(remap, marker, tmp, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       if (op != PT_BINOP_AND) {    if ((op == PT_BINOP_MINUS) && !tmp) {    tmp = a;    if (tmp) add_ref(tmp);    } else if ((op == PT_BINOP_MINUS) && (tmp == a)) {    free_type(tmp);    tmp = NULL;    } else {    free_type(tmp);    tmp = low_type_binop(op, a, b->cdr, remap,    aflags, bflags, remap_flags);    }    }       /* Value to backpatch. */ -  store_marker(remap, marker | 0x100, tmp); +  store_marker(remap, marker | 0x100, tmp, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       /* NB: We can only keep the marker assignment in the PT_BINOP_AND    * case.    *    * See also the b->type == '0'..'9' case further below.    */    if ((op == PT_BINOP_AND) && tmp) {    type_stack_mark();    push_finished_type(tmp);    push_assign_type(marker);
pike.git/src/pike_types.cmod:4873:    free_type(tmp);    return pop_unfinished_type();    }       /* Check consolidated types. */    switch(a?a->type:PIKE_T_UNKNOWN) {    case T_OR:    /* (a1 | a2) op b <==> (a1 op b) | (a2 op b) */    {    struct mapping *orig_markers = NULL; +  int marker_set = !!(remap_flags & PT_FLAG_REMAP_SWAP_MARKERS);    if (remap) {    /* Do not propagate marker changes between the branches    * of the T_OR node.    *    * FIXME: It is theoretically possible to propagate marker    * changes up if they are compatible in both branches.    */ -  orig_markers = remap->markers; -  remap->markers = copy_mapping(orig_markers); +  orig_markers = remap->markers[marker_set]; +  remap->markers[marker_set] = copy_mapping(orig_markers);    }    tmp = low_type_binop(op, a->car, b, remap, aflags, bflags, remap_flags);    if ((remap_flags & PT_FLAG_REMAP_INEXACT) && tmp) {    if ((op == PT_BINOP_AND) || (op == PT_BINOP_MINUS)) { -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    free_type(tmp);    add_ref(a);    return a;    }    } -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = copy_mapping(orig_markers); +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = copy_mapping(orig_markers);    }    tmp2 = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags); -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    }   #if 0    if ((op & PT_BINOP_NOT_A) || (aflags & PT_FLAG_CMP_INSEPARABLE)) {    if (!tmp2) {    free_type(tmp);    return NULL;    }    if (!tmp) {    free_type(tmp2);
pike.git/src/pike_types.cmod:4973:    push_finished_type(tmp2);    push_reverse_type(T_AND);    free_type(tmp);    free_type(tmp2);    return pop_unfinished_type();    }    switch(b?b->type:PIKE_T_UNKNOWN) {    case T_OR:    {    struct mapping *orig_markers = NULL; +  int marker_set = !(remap_flags & PT_FLAG_REMAP_SWAP_MARKERS);    if (remap) {    /* Do not propagate marker changes between the branches    * of the T_OR node.    *    * FIXME: It is theoretically possible to propagate marker    * changes up if they are compatible in both branches.    */ -  orig_markers = remap->markers; -  remap->markers = copy_mapping(orig_markers); +  orig_markers = remap->markers[marker_set]; +  remap->markers[marker_set] = copy_mapping(orig_markers);    }       tmp = low_type_binop(op, a, b->car, remap, aflags, bflags, remap_flags);    if (remap_flags & PT_FLAG_REMAP_INEXACT) {    if (tmp && (op == PT_BINOP_AND)) { -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    free_type(tmp);    add_ref(a);    return a;    } else if (!tmp && (op == PT_BINOP_MINUS)) { -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    return NULL;    }    } -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = copy_mapping(orig_markers); +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = copy_mapping(orig_markers);    }    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    * rather than    * A | (B | C) == (A | B) | (A | C)    */    tmp2 = remap_markers(b->cdr, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    ret = low_type_binop(op, tmp, tmp2, NULL, aflags, bflags, 0); -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    free_type(tmp);    free_type(tmp2);    return ret;    }    /* op secondary    * 0 0000 0 0000    * 1 0001 7 0111    * 2 0010 1 0001    * 3 0011 1, 3, 5, 7 0011
pike.git/src/pike_types.cmod:5050:    * 10 1010 1 0001    * 11 1011 1 0001    * 12 1100 1, 3, 5, 7 0011    * 13 1101 7 0111    * 14 1110 1 0001    * 15 1111 15 1111    *    * Note that secondary ops 1 and 7 are swapped for T_AND and T_OR.    */    tmp2 = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags); -  if (remap) { -  do_free_mapping(remap->markers); -  remap->markers = orig_markers; +  if (orig_markers) { +  do_free_mapping(remap->markers[marker_set]); +  remap->markers[marker_set] = orig_markers;    }    }       /* FIXME: XOR and XNOR not supported cf above. */    if ("071377-71-11371f"[op] == '1') {    /* Secondary operator is AND. */    if (!tmp2) {    free_type(tmp);    return NULL;    }
pike.git/src/pike_types.cmod:5166:    /*    * NB: At this point a and b are either NULL, a basic type or a marker.    */       loop:    switch(a ? a->type : PIKE_T_UNKNOWN) {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    {    int marker = remap_marker(remap, a->type, remap_flags); +  a = NULL;       if (!marker) { -  a = NULL; +     break;    }    -  a = lookup_marker(remap, marker); +  if (!lookup_marker(remap, marker, remap_flags, &a)) { +  break; +  }    -  if (!a) break; -  +     tmp = low_type_binop(op, a, b, remap, aflags, bflags, remap_flags);       free_type(a);    -  store_marker(remap, marker, tmp); +  store_marker(remap, marker, tmp, remap_flags);    if ((op == PT_BINOP_AND) || (op == PT_BINOP_MINUS)) { -  store_marker(remap, marker | 0x100, tmp); +  store_marker(remap, marker | 0x100, tmp, remap_flags);    }       if (!tmp) return NULL;    free_type(tmp);       type_stack_mark();    push_type(marker);    return pop_unfinished_type();    }    }    switch(b ? b->type : PIKE_T_UNKNOWN) {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    {    int marker = remap_marker(remap, b->type,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS); -  if (!marker) { +     b = NULL; -  +  +  if (!marker) {    break;    }    -  b = lookup_marker(remap, marker); +  if (!lookup_marker(remap, marker, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS, &b)) { +  break; +  }    -  if (!b) break; -  +     tmp = low_type_binop(op, a, b, remap, aflags, bflags, remap_flags);       free_type(b);       /* FIXME: Do we need to invert for PT_BINOP_MINUS here? */ -  store_marker(remap, marker, tmp); +  store_marker(remap, marker, tmp, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       /* NB: We can only keep the marker in the PT_BINOP_AND case,    * as in the other cases we do not have the corresponding    * assignment in the result.    *    * See also the b->type == T_ASSIGN case further above.    */    if ((op == PT_BINOP_AND) && tmp) { -  store_marker(remap, marker | 0x100, tmp); +  store_marker(remap, marker | 0x100, tmp, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);       free_type(tmp);    type_stack_mark();    push_type(marker);    return pop_unfinished_type();    }       return tmp;    }    }
pike.git/src/pike_types.cmod:6303:    enum pt_cmp_flags bflags,    enum pt_remap_flags remap_flags)   {    struct remap_state remap;    struct pike_type *ret;       INIT_REMAP_STATE(remap);       ret = low_type_binop(op, a, b, &remap, aflags, bflags, remap_flags);    -  if (remap.markers && ret && +  if ((remap.markers[0] || remap.markers[1]) && ret &&    ((op == PT_BINOP_AND) || (op == PT_BINOP_MINUS))) {    /* We may need to backpatch marker restrictions. */   #ifdef PIKE_DEBUG    if (l_flag > 1) {    fprintf(stderr, "Back-patching markers.\n"    "Original result: ");    simple_describe_type(ret); -  fprintf(stderr, "\nMarkers: "); -  simple_describe_mapping(remap.markers); +  fprintf(stderr, "\nMarkers[0]: "); +  simple_describe_mapping(remap.markers[0]); +  fprintf(stderr, "\nMarkers[1]: "); +  simple_describe_mapping(remap.markers[1]);    fprintf(stderr, "\n");    }   #endif    type_stack_mark(); -  push_and_fixup_markers(ret, &remap); +  push_and_fixup_markers(ret, &remap, remap_flags);    free_type(ret);    ret = pop_unfinished_type();   #ifdef PIKE_DEBUG    if (l_flag > 1) {    fprintf(stderr, "Result after back-patching: ");    simple_describe_type(ret);    fprintf(stderr, "\n");    }   #endif    }
pike.git/src/pike_types.cmod:9847:    struct pike_type **save_type_stackp = Pike_compiler->type_stackp;    struct pike_type ***save_mark_stackp = Pike_compiler->pike_type_mark_stackp;   #endif       INIT_REMAP_STATE(remap);       tmp = low_type_binop(PT_BINOP_MINUS, a, b, &remap, aflags, bflags,    PT_FLAG_REMAP_INEXACT);       if (tmp) { -  clear_mapping(remap.markers); +  clear_mapping(remap.markers[0]); +  clear_mapping(remap.markers[1]);       tmp2 = remap_markers(tmp, &remap, PT_FLAG_REMAP_EVAL_MARKERS);    }      #ifdef PIKE_EXTRA_DEBUG    clear_markers();    res = low_pike_types_le(a, b, 0, 0);       if ((save_type_stackp != Pike_compiler->type_stackp) ||    (save_mark_stackp != Pike_compiler->pike_type_mark_stackp) ||
pike.git/src/pike_types.cmod:9872:    "a: ");    simple_describe_type(a);    fprintf(stderr, "\nb: ");    simple_describe_type(b);    fprintf(stderr, "\nres: %d\ntmp: ", res);    simple_describe_type(tmp);    fprintf(stderr, "\ntmp2: ");    simple_describe_type(tmp2);    fprintf(stderr, "\n\n");    -  clear_mapping(remap.markers); +  clear_mapping(remap.markers[0]); +  clear_mapping(remap.markers[1]);       tmp3 = low_type_binop(PT_BINOP_MINUS, a, b, &remap,    aflags, bflags, PT_FLAG_REMAP_TRACE);    fprintf(stderr, "tmp3: ");    simple_describe_type(tmp3);    fprintf(stderr, "\n\n");       if ((save_type_stackp != Pike_compiler->type_stackp) ||    (save_mark_stackp != Pike_compiler->pike_type_mark_stackp)) {    Pike_fatal("Stack level corruption!\n"