pike.git / src / las.c

version» Context lines:

pike.git/src/las.c:283:    case F_RANGE_FROM_BEG:    case F_RANGE_FROM_END:    return 1;    case F_RANGE_OPEN:    return 0;       default:    if(n->type == void_type_string) return 0;    return 1;    } -  UNREACHABLE(); +  UNREACHABLE(return 0);   }      INT32 count_args(node *n)   {    int total = 0;    int a,b;    node *orig = n;    node *orig_parent;    node *prev = NULL;    check_tree(n,0);
pike.git/src/las.c:722:    {    default: return 0;    case F_ARG_LIST:    return is_automap_arg_list(CAR(n)) ||    is_automap_arg_list(CDR(n));       case F_AUTO_MAP_MARKER: return 1;    }   }    + static int apply_opt_flags_for_ref(struct program *prog, int fun);    -  + static int apply_opt_flags_for_sval(struct svalue *s) + { +  switch(TYPEOF(*s)) +  { +  case T_FUNCTION: +  if (SUBTYPEOF(*s) == FUNCTION_BUILTIN) +  { +  return s->u.efun->flags; +  } +  if (s->u.object->prog) { +  return apply_opt_flags_for_ref(s->u.object->prog, SUBTYPEOF(*s)); +  } +  yyerror("Calling function in destructed module."); +  break; +  +  case T_PROGRAM: +  if (s->u.program->flags & PROGRAM_CONSTANT) { +  return 0; +  } +  break; +  +  case T_OBJECT: +  if (!s->u.object->prog) { +  break; +  } +  return apply_opt_flags_for_ref(s->u.object->prog, +  FIND_LFUN(s->u.object->prog, LFUN_CALL)); +  } +  return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; + } +  + static int apply_opt_flags_for_ref(struct program *prog, int fun) + { +  if (!prog) { +  yyerror("Calling function in destructed object."); +  } else if (fun < 0) { +  yyerror("Attempt to call a missing function."); +  } else { +  struct identifier *id = ID_FROM_INT(prog, fun); +  struct program *p = PROG_FROM_INT(prog, fun); +  if (IDENTIFIER_IS_FUNCTION(id->identifier_flags)) { +  return id->opt_flags; +  } +  if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { +  DECLARE_CYCLIC(); +  struct svalue *s = &p->constants[id->func.const_info.offset].sval; +  int ret; +  if ((ret = (size_t)BEGIN_CYCLIC(p, s))) { +  return ret; +  } +  SET_CYCLIC_RET(OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND); +  ret = apply_opt_flags_for_sval(s); +  END_CYCLIC(); +  return ret; +  } +  } +  return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; + } +    node *debug_mknode(int token, node *a, node *b)   {    node *res;       switch(token)    {    case F_APPLY:    if(is_automap_arg_list(b))    token=F_AUTO_MAP;    break;
pike.git/src/las.c:831:    res->node_info |= OPT_SIDE_EFFECT;    if (a) {    res->tree_info |= a->tree_info & ~OPT_BREAK;    }    break;       case F_AUTO_MAP:    case F_APPLY:    {    unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; -  struct identifier *i = NULL; +        if (a) {    switch(a->token) {    case F_CONSTANT:    switch(TYPEOF(a->u.sval))    {    case T_FUNCTION: -  if (SUBTYPEOF(a->u.sval) == FUNCTION_BUILTIN) -  { -  opt_flags = a->u.sval.u.efun->flags; -  } else if (a->u.sval.u.object->prog) { -  i = ID_FROM_INT(a->u.sval.u.object->prog, SUBTYPEOF(a->u.sval)); -  } else { -  yyerror("Calling function in destructed module."); -  } +  opt_flags = apply_opt_flags_for_sval(&a->u.sval);    break;       case T_PROGRAM:    if(a->u.sval.u.program->flags & PROGRAM_CONSTANT) {    opt_flags=0;    }    if (a->u.sval.u.program->flags & PROGRAM_USES_PARENT) {    yyerror("Can not clone program without parent context.");    }    break;
pike.git/src/las.c:868:    break;    case F_EXTERNAL:    case F_GET_SET:    if (a->u.integer.b != IDREF_MAGIC_THIS) {    struct program_state *state = Pike_compiler;    int program_id = a->u.integer.a;    while (state && (state->new_program->id != program_id)) {    state = state->previous;    }    if (state) { -  i = ID_FROM_INT(state->new_program, a->u.integer.b); +  opt_flags = apply_opt_flags_for_ref(state->new_program, +  a->u.integer.b);    } else {    yyerror("Parent has left.");    }    }    break;    case F_LOCAL:    /* FIXME: Should lookup functions in the local scope. */    default:    res->tree_info |= a->tree_info;    } -  if (i && IDENTIFIER_IS_FUNCTION(i->identifier_flags)) { -  res->node_info |= i->opt_flags; -  } else { -  res->node_info |= opt_flags; +     } -  } else { -  res->node_info |= opt_flags; -  } -  res->node_info |= OPT_APPLY; +  res->node_info |= opt_flags | OPT_APPLY;    if(b) res->tree_info |= b->tree_info;    if (res->node_info & OPT_EXTERNAL_DEPEND) {    /* Applying something that has external dependencies    * renders a result that isn't constant.    */    res->tree_info |= OPT_NOT_CONST;    }    }    break;   
pike.git/src/las.c:912:    if(b) res->tree_info |= b->tree_info;    break;       case F_MAGIC_SET_INDEX:    res->node_info |= OPT_ASSIGNMENT;    /* FALLTHRU */    case F_MAGIC_INDEX:    case F_MAGIC_INDICES:    case F_MAGIC_VALUES:    case F_MAGIC_TYPES: +  case F_MAGIC_ANNOTATIONS:    {    int e;    struct program_state *state = Pike_compiler;    res->node_info |= OPT_EXTERNAL_DEPEND;    if (!b) break; /* Paranoia; probably compiler error. */    for(e=0;e<b->u.sval.u.integer;e++)    {    state->new_program->flags |= PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;    state=state->previous;    }
pike.git/src/las.c:997:    }    break;       case ':':    case F_RANGE_FROM_BEG:    case F_RANGE_FROM_END:    case F_RANGE_OPEN:    res->node_info |= OPT_FLAG_NODE;    break;    +  case F_SET_LOCAL_NAME: +  case F_SET_LOCAL_TYPE: +  case F_SET_LOCAL_END: +  /* Protect against the node being removed by the optimizer. */ +  res->node_info |= OPT_NOT_CONST|OPT_SIDE_EFFECT; +  break; +     default:    if(a) res->tree_info |= a->tree_info;    if(b) res->tree_info |= b->tree_info;    }       /* We try to optimize most things, but argument lists are hard... */    if((token != F_ARG_LIST) && (a || b))    res->node_info |= OPT_TRY_OPTIMIZE;       res->tree_info |= res->node_info;
pike.git/src/las.c:1023:    check_tree(res,0);      #ifdef PIKE_DEBUG    if(d_flag > 3)    verify_shared_strings_tables();   #endif       return res;   }    + static node *vmknestednodes(int token, va_list args) + { +  node *n = va_arg(args, node *); +  if (!n) return n; +  return mknode(token, n, vmknestednodes(token, args)); + } +  + node *mknestednodes(int token, ...) + { +  va_list args; +  node *res; +  va_start(args, token); +  res = vmknestednodes(token, args); +  va_end(args); +  return res; + } +    node *debug_mkstrnode(struct pike_string *str)   {    node *res = mkemptynode();    res->token = F_CONSTANT;    SET_SVAL(res->u.sval, T_STRING, 0, string, str);    add_ref(str);    res->type = get_type_of_svalue(&res->u.sval);    res->tree_info = OPT_SAFE;    return res;   }
pike.git/src/las.c:3763:    }       if ((n->type = new_get_return_type(dmalloc_touch(struct pike_type *, f),    0))) {    /* Type/argument-check OK. */    debug_malloc_touch(n->type);       free_type(f);    if(n->token == F_AUTO_MAP)    { +  type_stack_mark();    push_finished_type(n->type);    push_type(T_ARRAY);    free_type(n->type); -  n->type = pop_type(); +  n->type = pop_unfinished_type();    }    break;    }       /* Too few arguments or similar. */    copy_pike_type(n->type, mixed_type_string);       if ((s = get_first_arg_type(dmalloc_touch(struct pike_type *, f),    CALL_NOT_LAST_ARG))) {    yytype_report(REPORT_ERROR, NULL, 0, s,
pike.git/src/las.c:3855:    break;    }    }    else if(Pike_compiler->compiler_frame &&    Pike_compiler->compiler_frame->current_return_type)    {    struct pike_type *t = Pike_compiler->compiler_frame->current_return_type;       if( t->type == PIKE_T_AUTO )    { +  type_stack_mark();    if( t->car != zero_type_string )    {    /* Not the first one.. */    struct pike_type *t2;    push_finished_type( t2 = or_pike_types( t->car, CAR(n)->type, 1 ) );    free_type(t2);    }    else    {    /* first one.. */    push_finished_type(CAR(n)->type);    }    push_type(PIKE_T_AUTO);    free_type( t ); -  t = pop_type(); +  t = pop_unfinished_type();    Pike_compiler->compiler_frame->current_return_type = t;    } else {    node *retval = CAR(n);    if (retval->token == F_COMMA_EXPR) {    retval = CDR(retval);    }    if ((Pike_compiler->compiler_frame->current_return_type !=    void_type_string) ||    (retval->token != F_CONSTANT) ||    !SAFE_IS_ZERO(&retval->u.sval)) {
pike.git/src/las.c:4041:    }    free_type(sscanf_type);    }    if (!n->type) {    MAKE_CONSTANT_TYPE(n->type, tIntPos);    }    }    break;       case F_TYPEOF: +  type_stack_mark();    if (CAR(n)) {    push_finished_type(CAR(n)->type);    } else {    push_finished_type(mixed_type_string);    }    push_type(T_TYPE);    if (n->type) free_type(n->type); -  n->type = pop_type(); +  n->type = pop_unfinished_type();    break;       case F_UNDEFINED:    copy_pike_type(n->type, zero_type_string);    break;       case F_ARG_LIST:    if (n->parent) {    /* Propagate the changed type all the way up to the apply node. */    n->parent->node_info |= OPT_TYPE_NOT_FIXED;
pike.git/src/las.c:4120:    MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_INDICES);    break;    case F_MAGIC_VALUES:    /* FIXME: Could have a stricter type for ::_values. */    MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_VALUES);    break;    case F_MAGIC_TYPES:    /* FIXME: Could have a stricter type for ::_types. */    MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_TYPES);    break; +  case F_MAGIC_ANNOTATIONS: +  /* FIXME: Could have a stricter type for ::_annotations. */ +  MAKE_CONSTANT_TYPE(n->type, tF_MAGIC_ANNOTATIONS); +  break;    -  +  case F_SET_LOCAL_NAME: +  case F_SET_LOCAL_TYPE: +  case F_SET_LOCAL_END: +  copy_pike_type(n->type, void_type_string); +  break; +     case F_CATCH:    /* FALLTHRU */    default:    copy_pike_type(n->type, mixed_type_string);    }       if (n->type != old_type) {    if (n->parent) {    n->parent->node_info |= OPT_TYPE_NOT_FIXED;    }