pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:187:    default: return "unknown";      #ifdef PIKE_DEBUG    /* Let's make it able to describe any type constant in debug mode. */    case T_UNFINISHED: return "T_UNFINISHED";    case T_MANY: return "T_MANY";    case PIKE_T_INT_UNTYPED: return "PIKE_T_INT_UNTYPED";    case PIKE_T_GET_SET: return "PIKE_T_GET_SET";    case PIKE_T_FREE: return "PIKE_T_FREE";    case PIKE_T_FUNCTION_ARG: return "PIKE_T_FUNCTION_ARG"; +  +  case PIKE_T_FIND_LFUN: return "PIKE_T_FIND_LFUN"; +     case PIKE_T_ATTRIBUTE: return "PIKE_T_ATTRIBUTE";    case PIKE_T_NSTRING: return "PIKE_T_NSTRING";    case PIKE_T_LSTRING: return "PIKE_T_LSTRING";    case PIKE_T_LARRAY: return "PIKE_T_LARRAY";    case PIKE_T_RING: return "PIKE_T_RING";    case PIKE_T_NAME: return "PIKE_T_NAME";    case PIKE_T_SCOPE: return "PIKE_T_SCOPE";    case PIKE_T_TUPLE: return "PIKE_T_TUPLE";    case T_ASSIGN: return "T_ASSIGN";    case T_DELETED: return "T_DELETED";
pike.git/src/pike_types.cmod:257:    * STRING len type ZERO, INT or OR len:8.1, Range:7.7    * TYPE type -    * PROGRAM type -    * MIXED - -    * VOID - -    * ZERO - -    * UNKNOWN - -    * INT min (int) max (int)    * OBJECT implements/is object id(int)    * OPERATOR type Depends on bit #15. Added in 8.1 +  * FIND_LFUN object type lfun (int) Added in 8.1    *    * Note that the cdr of a FUNCTION is a valid FUNCTION for the rest of    * the arguments.    *    * Note also that functions that don't take any arguments, or just    * a many argument just have a MANY node, and no FUNCTION node.    *    */   static struct block_allocator type_allocator = BA_INIT(sizeof(struct pike_type), 128);   
pike.git/src/pike_types.cmod:2149:    case T_AND: fprintf(stderr, "and"); break;    case T_NOT: fprintf(stderr, "not"); break;    case T_VOID: fprintf(stderr, "void"); break;    case T_ZERO: fprintf(stderr, "zero"); break;    case T_MIXED: fprintf(stderr, "mixed"); break;       case PIKE_T_OPERATOR:    fprintf(stderr, "operator ");    e++;    switch(EXTRACT_UCHAR(a+e)<<8 | PIKE_T_OPERATOR) { +  case PIKE_T_FIND_LFUN: fprintf(stderr, "find_lfun"); break;    default:    fprintf(stderr, "unknown<0x%04x>",    EXTRACT_UCHAR(a+e)<<8 | PIKE_T_OPERATOR);    break;    }    break;       default: fprintf(stderr, "%d",EXTRACT_UCHAR(a+e)); break;    }    }
pike.git/src/pike_types.cmod:2441:    break;       case PIKE_T_OPERATOR:    fprintf(stderr, "operator<0x%04x>(", s->type);    simple_describe_type(s->car);    if (s->type & 0x8000) {    fprintf(stderr, ",");    simple_describe_type(s->cdr);    } else {    switch(s->type) { +  case PIKE_T_FIND_LFUN: +  fprintf(stderr, ",\"%s\")", STR0(lfun_strings[CDR_TO_INT(s)])); +  break;    default:    if (s->cdr) {    fprintf(stderr, ",0x%08lx)", CDR_TO_INT(s));    } else {    fprintf(stderr, ")");    }    break;    }    }    break;
pike.git/src/pike_types.cmod:2763:    string_builder_strcat(s, "mapping");    }    break;    case PIKE_T_AUTO:    if (t->car->type != T_ZERO) {    string_builder_sprintf(s, "auto(%T)", t->car);    } else {    string_builder_strcat(s, "auto");    }    break; +  +  case PIKE_T_FIND_LFUN: +  string_builder_sprintf(s, "find_lfun(%T, \"%S\")", +  t->car, lfun_strings[CDR_TO_INT(t)]); +  break; +     default:    {    if ((t->type & 0xff) == PIKE_T_OPERATOR) {    string_builder_sprintf(s, "operator(0x%04x)(%T", t->type, t->car);    if (t->type & 0x8000) {    string_builder_sprintf(s, ",%T)", t->cdr);    } else if (t->cdr) {    string_builder_sprintf(s, ",0x%08lx)", CDR_TO_INT(t));    } else {    string_builder_strcat(s, ")");
pike.git/src/pike_types.cmod:2827:       case T_ZERO:    return T_INT;       case T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    return compile_type_to_runtime_type(t->cdr);       case T_MANY: +  case PIKE_T_FIND_LFUN:    return T_FUNCTION;       case T_ARRAY:    case T_MAPPING:    case T_MULTISET:       case T_OBJECT:    case T_PROGRAM:    case T_FUNCTION:   
pike.git/src/pike_types.cmod:3545:    t->type);    }   #endif /* PIKE_DEBUG */    p = id_to_program(CDR_TO_INT(t));    if(!p) return 0;    i=FIND_LFUN(p, lfun);    if(i==-1) return 0;    return ID_FROM_INT(p, i)->type;   }    + /** +  * This function differs from low_object_lfun_type() above in +  * that it handles more cases, falls back to the default lfun +  * type (with a warning), and adds a reference to the returned +  * type. +  */ + static struct pike_type *find_lfun_type(struct pike_type *t, int lfun) + { +  struct pike_type *ret = NULL; +  struct svalue *s;    -  +  if (!t) return NULL;    -  +  loop: +  switch(t->type) { +  case PIKE_T_NAME: +  case PIKE_T_ATTRIBUTE: +  t = t->cdr; +  goto loop; +  +  case T_OBJECT: +  { +  struct program *p = NULL; +  if (t->cdr) { +  p = id_to_program(CDR_TO_INT(t)); +  } +  if (p) { +  int f = FIND_LFUN(p, lfun); +  +  if (f != -1) { +  struct identifier *id = ID_FROM_INT(p, f); +  ret = id->type; +  add_ref(ret); +  return ret; +  } +  ref_push_string(lfun_strings[lfun]); +  yytype_report(REPORT_WARNING, NULL, 0, NULL, +  NULL, 0, t, +  1, "Expected object implementing lfun %s."); +  } +  break; +  } +  case T_PROGRAM: +  t = t->car; +  goto loop; +  +  case T_FUNCTION: +  case T_MANY: +  t = t->cdr; +  goto loop; +  +  case T_OR: +  case T_AND: +  type_stack_mark(); +  push_finished_type(find_lfun_type(t->car, lfun)); +  push_finished_type(find_lfun_type(t->cdr, lfun)); +  push_type(t->type); +  return pop_unfinished_type(); +  +  case T_MIXED: +  case T_ZERO: +  case T_VOID: +  break; +  +  default: +  ref_push_string(lfun_strings[lfun]); +  yytype_report(REPORT_WARNING, NULL, 0, NULL, +  NULL, 0, t, +  1, "Expected object implementing lfun %s."); +  break; +  } +  + #if 0 +  /* FIXME: This does not work, as lfun_types contains narrow types +  * (zero for arguments, etc), while we here want the wide type +  * (mixed for arguments, etc). +  */ +  s = low_mapping_string_lookup(lfun_types, lfun_strings[lfun]); +  + #ifdef PIKE_DEBUG +  if (!s) { +  Pike_fatal("Unknown lfun: %s\n", STR0(lfun_strings[lfun])); +  } + #endif +  +  if (TYPEOF(*s) == PIKE_T_TYPE) { +  ret = s->u.type; +  add_ref(ret); +  return ret; +  } +  +  return NULL; + #else +  add_ref(function_type_string); +  return function_type_string; + #endif + } +  +  +    /******/      /*    * match two type strings, return zero if they don't match, and return    * the part of 'a' that _did_ match if it did.    */   #ifdef PIKE_TYPE_DEBUG   static struct pike_type *low_match_types2(struct pike_type *a,    struct pike_type *b,    int flags);
pike.git/src/pike_types.cmod:8320:   */    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_FIND_LFUN: +  res = find_lfun_type(arg1, (ptrdiff_t)(void*)arg2); +  break;    default:    Pike_fatal("apply_type_operator(): Unknown operator: 0x%04x\n", op);    break;    }    if (!res) {    res = mixed_type_string;    add_ref(res);    }    return res;   }
pike.git/src/pike_types.cmod:8985:       case PIKE_T_OPERATOR:    {    type |= type_string[1]<<8;    if (type & 0x8000) {    low_make_pike_type(type_string + 2, cont);    low_make_pike_type(*cont, cont);    push_reverse_type(type);    } else {    switch(type) { +  case PIKE_T_FIND_LFUN: +  { +  struct pike_string *str; +  int lfun = -1; +  int i; +  low_make_pike_type(type_string + 2, cont); +  str = findstring((const char *)*cont); +  if (!str) { +  Pike_fatal("compile_type_string(): Invalid lfun name: \"%s\"\n", *cont); +  } +  for (i = 0; i < 256; i++) { +  if (lfun_strings[i] == str) { +  lfun = i; +  break; +  } +  } +  if (lfun == -1) { +  Pike_fatal("compile_type_string(): Unknown lfun: \"%s\"\n", *cont); +  } +  *cont += str->len + 1; +  +  push_type_operator(PIKE_T_FIND_LFUN, +  (struct pike_type *)(ptrdiff_t)lfun); +  break; +  } +     default:    Pike_fatal("compile_type_string(): Unknown operator: 0x%04x\n", type);    break;    }    }    break;    }   #ifdef PIKE_DEBUG    default:    Pike_fatal("compile_type_string(): Error in type string %d.\n", type);