pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:110:    else    Pike_error ("Expected integer as string index, got %s.\n",    get_name_of_type (TYPEOF(*ind)));    }       case T_FUNCTION:    case T_PROGRAM:    if (program_index_no_free(to, what, ind)) break;    goto index_error;    - #ifdef AUTO_BIGNUM +     case T_INT:    if (TYPEOF(*ind) == T_STRING && !IS_UNDEFINED (what)) {    INT_TYPE val = what->u.integer;       convert_svalue_to_bignum(what);    index_no_free(to, what, ind);    if(IS_UNDEFINED(to)) {    if (val) {    Pike_error("Indexing the integer %"PRINTPIKEINT"d "    "with unknown method \"%S\".\n",    val, ind->u.string);    } else {    Pike_error("Indexing the NULL value with \"%S\".\n",    ind->u.string);    }    }    break;    }       /* FALL_THROUGH */ - #endif /* AUTO_BIGNUM */ +        default:    index_error:    if (TYPEOF(*ind) == T_INT)    Pike_error ("Cannot index %s with %"PRINTPIKEINT"d.\n",    (TYPEOF(*what) == T_INT && !what->u.integer)?    "the NULL value":get_name_of_type(TYPEOF(*what)),    ind->u.integer);    else if (TYPEOF(*ind) == T_FLOAT)    Pike_error ("Cannot index %s with %"PRINTPIKEFLOAT"e.\n",
pike.git/src/operators.c:272: Inside #if defined(HAVE_ISINF)
  #ifdef HAVE_ISINF    isinf(sp[-1].u.float_number) ||   #endif   #ifdef HAVE_ISNAN    isnan(sp[-1].u.float_number) ||   #endif    0) {    Pike_error("Can't cast infinites or NaN to int.\n");    } else {    int i=DO_NOT_WARN((int)(sp[-1].u.float_number)); - #ifdef AUTO_BIGNUM +     if((i < 0 ? -i : i) < floor(fabs(sp[-1].u.float_number)))    {    /* Note: This includes the case when i = 0x80000000, i.e.    the absolute value is not computable. */    convert_stack_top_to_bignum();    return; /* FIXME: OK to return? Cast tests below indicates    we have to do this, at least for now... /Noring */    /* Yes, it is ok to return, it is actually an optimization :)    * /Hubbe    */    }    else - #endif /* AUTO_BIGNUM */ +     {    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, i);    }    }    break;       case T_STRING: -  /* This can be here independently of AUTO_BIGNUM. Besides, -  we really want to reduce the number of number parsers -  around here. :) /Noring */ - #ifdef AUTO_BIGNUM +     /* The generic function is rather slow, so I added this    * code for benchmark purposes. :-) /per    */    if( (sp[-1].u.string->len >= 10) || sp[-1].u.string->size_shift )    convert_stack_top_string_to_inumber(10);    else - #endif /* AUTO_BIGNUM */ +     {    INT_TYPE i = STRTOL(sp[-1].u.string->str, 0, 10);    free_string(sp[-1].u.string);    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, i);    }    break;       case PIKE_T_INT:    break;   
pike.git/src/operators.c:957:    return !s->u.integer;    case PIKE_T_FUNCTION:    if (SUBTYPEOF(*s) == FUNCTION_BUILTIN) return 0;    /* FALL_THROUGH */    case PIKE_T_OBJECT:    return !s->u.object->prog;    }    return 0;    case T_ASSIGN:    case PIKE_T_NAME: +  case PIKE_T_ATTRIBUTE:    type = type->cdr;    goto loop;    case T_AND:    if (!low_check_soft_cast(s, type->car)) return 0;    type = type->cdr;    goto loop;    case T_OR:    if (low_check_soft_cast(s, type->car)) return 1;    type = type->cdr;    goto loop;    case T_NOT:    return !low_check_soft_cast(s, type->car);    }    if ((TYPEOF(*s) == PIKE_T_INT) && !s->u.integer) return 1;    if (TYPEOF(*s) == type->type) { -  if (type->type == PIKE_T_INT) { +  switch(type->type) { +  case PIKE_T_INT:    if (((((INT32)CAR_TO_INT(type)) != MIN_INT32) &&    (s->u.integer < (INT32)CAR_TO_INT(type))) ||    ((((INT32)CDR_TO_INT(type)) != MAX_INT32) &&    (s->u.integer > (INT32)CDR_TO_INT(type)))) {    return 0;    }    return 1; -  } -  if (type->type == PIKE_T_FLOAT) return 1; -  if (type->type == PIKE_T_STRING) { +  case PIKE_T_FLOAT: +  return 1; +  case PIKE_T_STRING:    if ((8<<s->u.string->size_shift) > CAR_TO_INT(type)) {    return 0;    }    return 1; -  } -  switch(type->type) { +     case PIKE_T_OBJECT:    {    struct program *p;    /* Common cases. */    if (!type->cdr) return 1;    if (s->u.object->prog->id == CDR_TO_INT(type)) return 1;    p = id_to_program(CDR_TO_INT(type));    if (!p) return 1;    return implements(s->u.object->prog, p);    }
pike.git/src/operators.c:1073:      void o_check_soft_cast(struct svalue *s, struct pike_type *type)   {    if (!low_check_soft_cast(s, type)) {    /* Note: get_type_from_svalue() doesn't return a fully specified type    * for array, mapping and multiset, so we perform a more lenient    * check for them.    */    struct pike_type *sval_type = get_type_of_svalue(s);    struct pike_string *t1; -  struct pike_string *t2; +  struct string_builder s;    char *fname = "__soft-cast"; -  +  ONERROR tmp0;    ONERROR tmp1; -  ONERROR tmp2; +     -  +  init_string_builder(&s, 0); +  +  SET_ONERROR(tmp0, free_string_builder, &s); +  +  string_builder_explain_nonmatching_types(&s, type, sval_type); +     if (Pike_fp->current_program) {    /* Look up the function-name */    struct pike_string *name =    ID_FROM_INT(Pike_fp->current_program, Pike_fp->fun)->name;    if ((!name->size_shift) && (name->len < 100))    fname = name->str;    }       t1 = describe_type(type);    SET_ONERROR(tmp1, do_free_string, t1);    -  t2 = describe_type(sval_type); -  SET_ONERROR(tmp2, do_free_string, t2); -  +     free_type(sval_type);       bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1, -  "%s(): Soft cast failed. Expected %s, got %s\n", -  fname, t1->str, t2->str); +  "%s(): Soft cast failed.\n%S", +  fname, s.s);    /* NOT_REACHED */ -  UNSET_ONERROR(tmp2); -  UNSET_ONERROR(tmp1); -  free_string(t2); -  free_string(t1); +  CALL_AND_UNSET_ONERROR(tmp1); +  CALL_AND_UNSET_ONERROR(tmp0);    }   }      #define COMPARISON(ID,NAME,FUN) \   PMOD_EXPORT void ID(INT32 args) \   { \    int i; \    switch(args) \    { \    case 0: case 1: \
pike.git/src/operators.c:1547:    "string|object|int|float|array|mapping|multiset", sp-args,    "Incompatible types\n");    return; /* compiler hint */       case BIT_STRING:    {    struct pike_string *r;    PCHARP buf;    ptrdiff_t tmp;    int max_shift=0; -  +     if(args==1) return;       size=0;    for(e=-args;e<0;e++)    {    size+=sp[e].u.string->len;    if(sp[e].u.string->size_shift > max_shift)    max_shift=sp[e].u.string->size_shift;    }       if(size == sp[-args].u.string->len)    {    pop_n_elems(args-1);    return;    } -  +  else if(args == 2 && (size == sp[-1].u.string->len)) +  { +  stack_swap(); +  pop_stack(); +  return; +  }       tmp=sp[-args].u.string->len;    r=new_realloc_shared_string(sp[-args].u.string,size,max_shift);    mark_free_svalue (sp - args);    buf=MKPCHARP_STR_OFF(r,tmp);    for(e=-args+1;e<0;e++)    { -  +  if( sp[e].u.string->len ) +  { +  update_flags_for_add( r, sp[e].u.string );    pike_string_cpy(buf,sp[e].u.string);    INC_PCHARP(buf,sp[e].u.string->len);    } -  +  }    SET_SVAL(sp[-args], T_STRING, 0, string, low_end_shared_string(r)); -  for(e=-args+1;e<0;e++) free_string(sp[e].u.string); +  +  for(e=-args+1;e<0;e++) +  free_string(sp[e].u.string); +     sp-=args-1;       break;    }       case BIT_STRING | BIT_INT:    case BIT_STRING | BIT_FLOAT:    case BIT_STRING | BIT_FLOAT | BIT_INT:    {    struct pike_string *r;
pike.git/src/operators.c:1710:    }    }    r = realloc_unlinked_string(r, SUBTRACT_PCHARP(buf, MKPCHARP_STR(r)));    r = low_end_shared_string(r);    pop_n_elems(args);    push_string(r);    break;    }       case BIT_INT: - #ifdef AUTO_BIGNUM +  { +  int of = 0;    size = 0;    for(e = -args; e < 0; e++)    { -  if(INT_TYPE_ADD_OVERFLOW(sp[e].u.integer, size)) +  size = DO_INT_TYPE_ADD_OVERFLOW(size, sp[e].u.integer, &of); +  } +  if(of)    {    convert_svalue_to_bignum(sp-args);    f_add(args);    return;    } -  else -  { -  size += sp[e].u.integer; -  } -  } +     sp-=args;    push_int(size); - #else -  size=0; -  for(e=-args; e<0; e++) size+=sp[e].u.integer; -  sp-=args-1; -  SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer, size); - #endif /* AUTO_BIGNUM */ +     break;    -  +  }    case BIT_FLOAT:    if (args > 2) {    /* Attempt to minimize the accumulated summation error    * by adding the smallest (absolute) values first.    *    * Large accumulated errors can occur eg when the number    * of values to add is of the same order as the largest    * number representable by the mantissa alone. ie when    * the sum differs by an order of magnitude from a    * typical term.
pike.git/src/operators.c:2233:    {    SET_SVAL(sp[-2], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-2].u.integer);    return 1;    }    else if(TYPEOF(sp[-1]) == T_INT && TYPEOF(sp[-2]) == T_FLOAT)    {    SET_SVAL(sp[-1], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-1].u.integer);    return 1;    }    - #ifdef AUTO_BIGNUM +     if(is_bignum_object_in_svalue(sp-2) && TYPEOF(sp[-1]) == T_FLOAT)    {    stack_swap();    ref_push_type_value(float_type_string);    stack_swap();    f_cast();    stack_swap();    return 1;    }    else if(is_bignum_object_in_svalue(sp-1) && TYPEOF(sp[-2]) == T_FLOAT)    {    ref_push_type_value(float_type_string);    stack_swap();    f_cast();    return 1;    } - #endif +     return 0;   }      static int call_lfun(int left, int right)   {    struct object *o;    struct program *p;    int i;       if(TYPEOF(sp[-2]) == T_OBJECT &&
pike.git/src/operators.c:2389:    push_multiset(l);    return;    }       case T_FLOAT:    sp--;    sp[-1].u.float_number -= sp[0].u.float_number;    return;       case T_INT: - #ifdef AUTO_BIGNUM +     if(INT_TYPE_SUB_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))    {    convert_stack_top_to_bignum();    f_minus(2);    return;    } - #endif /* AUTO_BIGNUM */ +     sp--;    SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer,    sp[-1].u.integer - sp[0].u.integer);    return;       case T_STRING:    {    struct pike_string *s,*ret;    s=make_shared_string("");    ret=string_replace(sp[-2].u.string,sp[-1].u.string,s);
pike.git/src/operators.c:3410:    modify_stack_depth(-1);    return 1;       default:    return 0;    }   }      PMOD_EXPORT void o_lsh(void)   { - #ifdef AUTO_BIGNUM +     if ((TYPEOF(sp[-1]) == T_INT) && (TYPEOF(sp[-2]) == T_INT) &&    INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))    convert_stack_top_to_bignum(); - #endif /* AUTO_BIGNUM */ +        if(TYPEOF(sp[-1]) != T_INT || TYPEOF(sp[-2]) != T_INT)    {    int args = 2;    if(call_lfun(LFUN_LSH, LFUN_RLSH))    return;       if(TYPEOF(sp[-2]) != T_INT)    SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object");    SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");    } - #ifndef AUTO_BIGNUM -  if (sp[-1].u.integer > 31) { -  sp--; -  SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, 0); -  return; -  } - #endif /* !AUTO_BIGNUM */ +     if (sp[-1].u.integer < 0) {    int args = 2;    SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");    }    sp--;    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer,    sp[-1].u.integer << sp->u.integer);   }      /*! @decl int `<<(int arg1, int arg2)
pike.git/src/operators.c:3502:    if(TYPEOF(sp[-2]) != T_INT)    SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object");    SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object");    }       if (sp[-1].u.integer < 0) {    int args = 2;    SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object");    }    -  if( - #ifdef AUTO_BIGNUM -  (INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) - #else /* !AUTO_BIGNUM */ -  (sp[-1].u.integer > 31) - #endif /* AUTO_BIGNUM */ -  ) +  if( INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer) )    {    sp--;    if (sp[-1].u.integer < 0) {    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, -1);    } else {    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, 0);    }    return;    }   
pike.git/src/operators.c:3732:    return;       case TWO_TYPES(T_INT,T_FLOAT):    sp--;    sp[-1].u.float_number=    (FLOAT_TYPE) sp[-1].u.integer * sp[0].u.float_number;    SET_SVAL_TYPE(sp[-1], T_FLOAT);    return;       case TWO_TYPES(T_INT,T_INT): - #ifdef AUTO_BIGNUM -  if(INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) +     { -  +  INT_TYPE res; +  int of = 0; +  +  res = DO_INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer, &of); +  +  if(of) +  {    convert_stack_top_to_bignum();    goto do_lfun_multiply;    } - #endif /* AUTO_BIGNUM */ +     sp--; -  SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, -  sp[-1].u.integer * sp[0].u.integer); +  SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, res);    return; -  +  }    default:    do_lfun_multiply:    if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))    return;       PIKE_ERROR("`*", "Bad arguments.\n", sp, 2);    }   }      /*! @decl mixed `*(mixed arg1)
pike.git/src/operators.c:4080:       case T_INT:    {    INT_TYPE tmp;       if (sp[-1].u.integer == 0)    OP_DIVISION_BY_ZERO_ERROR("`/");       if(INT_TYPE_DIV_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))    { - #ifdef AUTO_BIGNUM +     stack_swap();    convert_stack_top_to_bignum();    stack_swap();    goto do_lfun_division; - #else -  /* It's not possible to do MININT/-1 (it gives FPU exception on -  some CPU:s), thus we return what MININT*-1 returns: MININT. */ -  tmp = sp[-2].u.integer; - #endif /* AUTO_BIGNUM */ +     }    else    tmp = sp[-2].u.integer/sp[-1].u.integer;    sp--;       /* What is this trying to solve? /Noring */    /* It fixes rounding towards negative infinity. /mast */    if((sp[-1].u.integer<0) != (sp[0].u.integer<0))    if(tmp*sp[0].u.integer!=sp[-1].u.integer)    tmp--;
pike.git/src/operators.c:4217:    modify_stack_depth(-1);    return 1;    }    return 0;   }      PMOD_EXPORT void o_mod(void)   {    if(TYPEOF(sp[-2]) != TYPEOF(sp[-1]) && !float_promote())    { + do_lfun_modulo:    if(call_lfun(LFUN_MOD, LFUN_RMOD))    return;       switch(TWO_TYPES(TYPEOF(sp[-2]), TYPEOF(sp[-1])))    {    case TWO_TYPES(T_STRING,T_INT):    {    struct pike_string *s=sp[-2].u.string;    ptrdiff_t tmp,base;   
pike.git/src/operators.c:4291:    OP_MODULO_BY_ZERO_ERROR("`%");    sp--;    foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number /    sp[0].u.float_number));    foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number -    sp[0].u.float_number * floor(foo)));    sp[-1].u.float_number=foo;    return;    }    case T_INT: -  if (sp[-1].u.integer == 0) +  { +  int of = 0; +  INT_TYPE a = sp[-2].u.integer, +  b = sp[-1].u.integer; +  INT_TYPE res; +  if (b == 0)    OP_MODULO_BY_ZERO_ERROR("`%"); -  sp--; -  if(sp[-1].u.integer>=0) +  if(a>=0)    { -  if(sp[0].u.integer>=0) +  if(b>=0)    { -  sp[-1].u.integer %= sp[0].u.integer; +  res = a % b;    }else{ -  sp[-1].u.integer=((sp[-1].u.integer+~sp[0].u.integer)%-sp[0].u.integer)-~sp[0].u.integer; +  /* res = ((a+~b)%-b)-~b */ +  res = DO_INT_TYPE_ADD_OVERFLOW(a, ~b, &of); +  res = DO_INT_TYPE_MOD_OVERFLOW(res, b, &of); +  res = DO_INT_TYPE_SUB_OVERFLOW(res, ~b, &of);    }    }else{ -  if(sp[0].u.integer>=0) +  if(b>=0)    { -  sp[-1].u.integer=sp[0].u.integer+~((~sp[-1].u.integer) % sp[0].u.integer); +  /* res = b+~((~a) % b) */ +  res = DO_INT_TYPE_MOD_OVERFLOW(~a, b, &of); +  res = DO_INT_TYPE_ADD_OVERFLOW(b, ~res, &of);    }else{ -  sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer); +  /* a % b and a % -b are equivalent, if overflow does not +  * happen +  * res = -(-a % -b) = a % b; */ +  res = DO_INT_TYPE_MOD_OVERFLOW(a, b, &of);    }    } -  SET_SVAL_SUBTYPE(sp[-1], NUMBER_NUMBER); +  if (of) { +  stack_swap(); +  convert_stack_top_to_bignum(); +  stack_swap(); +  goto do_lfun_modulo; +  } +  sp--; +  SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, res);    return; -  +  }    default:    PIKE_ERROR("`%", "Bad argument 1.\n", sp, 2);    }   }      /*! @decl mixed `%(object arg1, mixed arg2)    *! @decl mixed `%(mixed arg1, object arg2)    *! @decl string `%(string arg1, int arg2)    *! @decl array `%(array arg1, int arg2)    *! @decl float `%(float arg1, float|int arg2)
pike.git/src/operators.c:4607:    case T_OBJECT:    do_lfun_negate:    CALL_OPERATOR(LFUN_SUBTRACT,1);    break;       case T_FLOAT:    sp[-1].u.float_number=-sp[-1].u.float_number;    return;       case T_INT: - #ifdef AUTO_BIGNUM +     if(INT_TYPE_NEG_OVERFLOW(sp[-1].u.integer))    {    convert_stack_top_to_bignum();    goto do_lfun_negate;    } - #endif /* AUTO_BIGNUM */ +     SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, -sp[-1].u.integer);    return;       default:    PIKE_ERROR("`-", "Bad argument to unary minus.\n", sp, 1);    }   }      static void string_or_array_range (int bound_types,    struct svalue *ind,
pike.git/src/operators.c:5650:    sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j);    assign_lvalue(THIS->lval, sp-1);    pop_stack();    }       pop_n_elems(args);    push_int(j);   }       - static void init_string_assignment_storage(struct object *o) + static void init_string_assignment_storage(struct object *UNUSED(o))   {    SET_SVAL(THIS->lval[0], T_INT, PIKE_T_FREE, integer, 0);    SET_SVAL(THIS->lval[1], T_INT, PIKE_T_FREE, integer, 0);    THIS->s = NULL;   }    - static void exit_string_assignment_storage(struct object *o) + static void exit_string_assignment_storage(struct object *UNUSED(o))   {    free_svalues(THIS->lval, 2, BIT_MIXED);    if(THIS->s)    free_string(THIS->s);   }      /*! @endclass    */      void init_operators(void)
pike.git/src/operators.c:5746:    add_efun2("`>", f_gt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);    add_efun2("`>=",f_ge,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);       ADD_EFUN2("`+",f_add,    tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),    tFuncV(tNone,tMix,tMix)),    tFuncV(tInt,tInt,tInt),    tIfnot(tFuncV(tNone, tNot(tFlt), tMix),    tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),    tIfnot(tFuncV(tNone, tNot(tStr), tMix), -  tFuncV(tOr3(tStr,tInt,tFlt), -  tOr3(tStr,tInt,tFlt),tStr)), +  tFuncV(tOr3(tSetvar(0, tStr),tInt,tFlt), +  tOr3(tSetvar(1, tStr),tInt,tFlt),tOr(tVar(0),tVar(1)))),    tFuncV(tSetvar(0,tArray),tSetvar(1,tArray),    tOr(tVar(0),tVar(1))),    tFuncV(tSetvar(0,tMapping),tSetvar(1,tMapping),    tOr(tVar(0),tVar(1))),    tFuncV(tSetvar(0,tMultiset),tSetvar(1,tMultiset),    tOr(tVar(0),tVar(1)))),    OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);       ADD_EFUN2("`-",f_minus,    tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),    tFuncV(tNone,tMix,tMix)),    tFuncV(tInt,tInt,tInt),    tIfnot(tFuncV(tNone,tNot(tFlt),tMix),    tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),    tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))),    tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)),    tOr3(tMapping,tArray,tMultiset),    tMap(tVar(1),tVar(2))),    tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))), -  tFuncV(tStr,tStr,tStr)), +  tFuncV(tSetvar(0,tStr),tStr,tVar(0))),    OPT_TRY_OPTIMIZE,0,generate_minus);      /*      object & mixed -> mixed   mixed & object -> mixed      int & int -> int   array & array -> array   multiset & multiset -> multiset
pike.git/src/operators.c:5911:       /* function(object:mixed)|function(int:int)|function(float:float)|function(string:string) */    ADD_EFUN2("`~",f_compl,    tOr6(tFunc(tObj,tMix),    tFunc(tInt,tInt),    tFunc(tFlt,tFlt),    tFunc(tStr,tStr),    tFunc(tType(tSetvar(0, tMix)), tType(tNot(tVar(0)))),    tFunc(tPrg(tObj), tType(tMix))),    OPT_TRY_OPTIMIZE,0,generate_compl); -  /* function(string|multiset|array|mapping|object:int) */ +  /* function(string|multiset|array|mapping|object:int(0..)) */    ADD_EFUN2("sizeof", f_sizeof, -  tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt), +  tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tIntPos),    OPT_TRY_OPTIMIZE, optimize_sizeof, generate_sizeof);       /* function(mixed,mixed ...:mixed) */    ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);       /* This one should be removed */    /* function(mixed,mixed ...:mixed) */    ADD_EFUN2("call_function",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);       /* From the 201x C standard */