pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:172:      static struct switch_data current_switch = {0, 0, 0, 0, 0, NULL, NULL};      void upd_int(int offset, INT32 tmp)   {    memcpy(Pike_compiler->new_program->program+offset, &tmp, sizeof(tmp));   }      INT32 read_int(int offset)   { -  return EXTRACT_INT(Pike_compiler->new_program->program+offset); +  return (INT32)get_unaligned32(Pike_compiler->new_program->program+offset);   }      static int label_no=0;      int alloc_label(void) { return ++label_no; }      int do_jump(int token,INT32 lbl)   {    struct compilation *c = THIS_COMPILATION;    if(lbl==-1) lbl=alloc_label();
pike.git/src/docode.c:262: Inside #if defined(PIKE_DEBUG)
   struct compilation *c = THIS_COMPILATION;   #ifdef PIKE_DEBUG    if (x < 0) Pike_fatal("Cannot do pop of %d args.\n", x);   #endif    switch(x)    {    case 0: return;    case 1: emit0(F_POP_VALUE); break;    default: emit1(F_POP_N_ELEMS,x); break;    } -  current_stack_depth -= x; +  modify_stack_depth(-x);   }      static void do_pop_mark(void *UNUSED(ignored))   {    struct compilation *c = THIS_COMPILATION;    emit0(F_POP_MARK);   }      static void do_pop_to_mark(void *UNUSED(ignored))   {
pike.git/src/docode.c:366:    do_cond_jump(CDR(n), label, iftrue, flags);    low_insert_label(tmp);    }else{    do_cond_jump(CAR(n), label, iftrue, flags);    do_cond_jump(CDR(n), label, iftrue, flags);    }    return;       case F_APPLY:    if(!is_efun(CAR(n), f_not)) break; +  /* FALLTHRU */       case F_NOT:    if(!(flags & DO_POP)) break;    do_cond_jump(CDR(n), label , !iftrue, flags | DO_NOT_COPY);    return;    default:    /* Inform gcc that we handle all the values in the enum. */    break;    }       code_expression(n, flags | DO_NOT_COPY, "condition");       if(flags & DO_POP)    {    if(iftrue)    do_jump(F_BRANCH_WHEN_NON_ZERO, label);    else    do_jump(F_BRANCH_WHEN_ZERO, label); -  current_stack_depth--; +  modify_stack_depth(-1);    }else{    if(iftrue)    do_jump(F_LOR, label);    else    do_jump(F_LAND, label);    }   }      #define do_jump_when_zero(N,L) do_cond_jump(N,L,0,DO_POP|DO_NOT_COPY)   #define do_jump_when_non_zero(N,L) do_cond_jump(N,L,1,DO_POP|DO_NOT_COPY)
pike.git/src/docode.c:900:    } else if (!level) {    f += inh->identifier_level;    emit0(F_MARK);    code_expression(val, 0, "RHS");    emit_multi_assign(vals, vars, no+1);    emit1(F_CALL_LFUN, f);    emit0(F_POP_VALUE);    }    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case F_EXTERNAL:    /* Check that it is in this context */    if(Pike_compiler ->new_program->id == var->u.integer.a)    {    /* Check that it is a variable */    if(var->u.integer.b != IDREF_MAGIC_THIS &&    IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, var->u.integer.b)->identifier_flags))    {    code_expression(val, 0, "RHS");    emit_multi_assign(vals, vars, no+1);
pike.git/src/docode.c:1243:    }       low_insert_label( (INT32)tmp2 );       current_switch.jumptable = prev_switch_jumptable;    return adroppings;    }       case F_MULTI_ASSIGN:    if (flags & DO_POP) { -  emit_multi_assign(CAR(n), CDR(n), 0); +  emit_multi_assign(CDR(n), CAR(n), 0);    return 0;    } else {    /* Fall back to the normal assign case. */ -  tmp1=do_docode(CDR(n),DO_LVALUE); +  tmp1=do_docode(CAR(n),DO_LVALUE);   #ifdef PIKE_DEBUG    if(tmp1 & 1)    Pike_fatal("Very internal compiler error.\n");   #endif    emit1(F_ARRAY_LVALUE, (INT32)(tmp1>>1) );    emit0(F_MARK);    PUSH_CLEANUP_FRAME(do_pop_mark, 0); -  do_docode(CAR(n), 0); +  do_docode(CDR(n), 0);    emit_apply_builtin("aggregate");    POP_AND_DONT_CLEANUP;    emit0(F_ASSIGN);    return 1;    }       case F_ASSIGN_SELF:    /* in assign self we know this:    *    * car(n) = lvalue    * cdr(n)= softcast(apply(efun, arglist(car(n),one more arg)))    *    * The first argument of the arglist is equal to the lvalue.    *    * We only want to evaluate car(n) once.    */ -  if( CDR(n)->token == F_AUTO_MAP_MARKER ) +  if( CAR(n)->token == F_AUTO_MAP_MARKER )    yyerror("[*] is not yet supported here\n"); -  return emit_ltosval_call_and_assign( CDR(n), CAAAR(n), CDAAR(n) ); +  return emit_ltosval_call_and_assign( CAR(n), CAADR(n), CDADR(n) );       case F_ASSIGN:    -  if( CDR(n)->token == F_AUTO_MAP_MARKER ) +  if( CAR(n)->token == F_AUTO_MAP_MARKER )    {    int depth = 0; -  node *lval = CDR(n); +  node *lval = CAR(n);    while( lval->token == F_AUTO_MAP_MARKER )    {    lval = CAR(lval);    depth++;    }    do_docode(lval,0); /* note: not lvalue */ -  if(do_docode(CAR(n),0)!=1) +  if(do_docode(CDR(n),0)!=1)    yyerror("RHS is void!");    -  if( CAR(n)->token == F_AUTO_MAP_MARKER || -  CAR(n)->token == F_AUTO_MAP || +  if( CDR(n)->token == F_AUTO_MAP_MARKER || +  CDR(n)->token == F_AUTO_MAP ||    /* Well, hello there... ;) */    /* This is what is generated by a[*] += 10 and such. */ -  (CAR(n)->token == F_SOFT_CAST && -  has_automap(CAR(n)))) +  (CDR(n)->token == F_SOFT_CAST && +  has_automap(CDR(n))))    {    emit1(F_ASSIGN_INDICES,depth);    }    else    {    emit1(F_ASSIGN_ALL_INDICES,depth);    }    if( flags & DO_POP )    emit0( F_POP_VALUE );    return !(flags&DO_POP);    }    -  switch(CAR(n)->token) +  switch(CDR(n)->token)    {    case F_RANGE: -  if(node_is_eq(CDR(n),CAAR(n))) +  if(node_is_eq(CAR(n),CADR(n)))    {    int num_args;    /* tmp1=do_docode(CDR(n),DO_LVALUE); */ -  if(match_types(CDR(n)->type, array_type_string) || -  match_types(CDR(n)->type, string_type_string) || -  match_types(CDR(n)->type, object_type_string) || -  match_types(CDR(n)->type, multiset_type_string) || -  match_types(CDR(n)->type, mapping_type_string)) +  if(match_types(CAR(n)->type, array_type_string) || +  match_types(CAR(n)->type, string_type_string) || +  match_types(CAR(n)->type, object_type_string) || +  match_types(CAR(n)->type, multiset_type_string) || +  match_types(CAR(n)->type, mapping_type_string))    { -  do_docode(CDR(n),DO_LVALUE); -  num_args = do_docode(CDAR(n), 0); +  do_docode(CAR(n),DO_LVALUE); +  num_args = do_docode(CDDR(n), 0);    switch (num_args)    {    case 0: emit0(F_LTOSVAL_AND_FREE); break;    case 1: emit0(F_LTOSVAL2_AND_FREE); break;    case 2: emit0(F_LTOSVAL3_AND_FREE); break;   #ifdef PIKE_DEBUG    default:    Pike_fatal("Arglebargle glop-glyf?\n");   #endif    }    }else{    goto do_not_suboptimize_assign;    emit0(F_LTOSVAL); -  num_args = do_docode(CDAR(n), 0); +  num_args = do_docode(CDDR(n), 0);    }    -  if (CAR (n)->token == F_RANGE) -  emit_range (CAR (n) DO_IF_DEBUG (COMMA num_args)); +  if (CDR (n)->token == F_RANGE) +  emit_range (CDR (n) DO_IF_DEBUG (COMMA num_args));    else -  emit0(CAR(n)->token); +  emit0(CDR(n)->token);       emit0(n->token);    return n->token==F_ASSIGN; /* So when is this false? /mast */    }    goto do_not_suboptimize_assign;       case F_SOFT_CAST:    /* a = [type]`oper(a,*) */ -  if( CAAR(n)->token == F_APPLY && -  is_apply_constant_function_arg0( CAAR(n), CDR(n) )) +  if( CADR(n)->token == F_APPLY && +  is_apply_constant_function_arg0( CADR(n), CAR(n) ))    return 1;    goto do_not_suboptimize_assign;    case F_APPLY:    /* a = `oper(a,*) */ -  if (is_apply_constant_function_arg0( CAR(n), CDR(n) )) +  if (is_apply_constant_function_arg0( CDR(n), CAR(n) ))    return 1; -  /* FALL_THROUGH */ +  /* FALLTHRU */    default:    do_not_suboptimize_assign: -  switch(CDR(n)->token) +  switch(CAR(n)->token)    {    case F_GLOBAL: -  if(CDR(n)->u.integer.b) goto normal_assign; -  code_expression(CAR(n), 0, "RHS"); -  emit_assign_global( CDR(n)->u.integer.a, flags & DO_POP ); +  if(CAR(n)->u.integer.b) goto normal_assign; +  code_expression(CDR(n), 0, "RHS"); +  emit_assign_global( CAR(n)->u.integer.a, flags & DO_POP );    break;    case F_LOCAL: -  if(CDR(n)->u.integer.a >= -  find_local_frame(CDR(n)->u.integer.b)->max_number_of_locals) +  if(CAR(n)->u.integer.a >= +  find_local_frame(CAR(n)->u.integer.b)->max_number_of_locals)    yyerror("Illegal to use local variable here.");    -  if(CDR(n)->u.integer.b) goto normal_assign; +  if(CAR(n)->u.integer.b) goto normal_assign;    -  if (CDR(n)->node_info & OPT_ASSIGNMENT) { +  if (CAR(n)->node_info & OPT_ASSIGNMENT) {    /* Initialize. */    emit0(F_CONST0); -  emit1(F_ASSIGN_LOCAL_AND_POP, CDR(n)->u.integer.a); +  emit1(F_ASSIGN_LOCAL_AND_POP, CAR(n)->u.integer.a);    } -  code_expression(CAR(n), 0, "RHS"); +  code_expression(CDR(n), 0, "RHS");    emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL, -  CDR(n)->u.integer.a ); +  CAR(n)->u.integer.a );    break;       case F_GET_SET:    {    /* Check for the setter function. */    struct program_state *state = Pike_compiler; -  int program_id = CDR(n)->u.integer.a; +  int program_id = CAR(n)->u.integer.a;    int level = 0;    while (state && (state->new_program->id != program_id)) {    state = state->previous;    level++;    }    if (!state) {    yyerror("Lost parent.");    } else {    struct reference *ref = -  PTR_FROM_INT(state->new_program, CDR(n)->u.integer.b); +  PTR_FROM_INT(state->new_program, CAR(n)->u.integer.b);    struct identifier *id =    ID_FROM_PTR(state->new_program, ref);    struct inherit *inh =    INHERIT_FROM_PTR(state->new_program, ref);    int f;   #ifdef PIKE_DEBUG    if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags) ||    (id->run_time_type != PIKE_T_GET_SET)) {    Pike_fatal("Not a getter/setter in a F_GET_SET node!\n"    " identifier_flags: 0x%08x\n"
pike.git/src/docode.c:1427:   #endif /* PIKE_DEBUG */    f = id->func.gs_info.setter;    if (f == -1) {    yywarning("Variable %S lacks a setter.", id->name);    } else if (!level) {    f += inh->identifier_level;    if (flags & DO_POP) {   #ifndef USE_APPLY_N    emit0(F_MARK);   #endif -  code_expression(CAR(n), 0, "RHS"); +  code_expression(CDR(n), 0, "RHS");    } else {    code_expression(CAR(n), 0, "RHS");   #ifndef USE_APPLY_N    emit0(F_MARK);   #endif    emit0(F_DUP);    }   #ifdef USE_APPLY_N    emit2(F_CALL_LFUN_N, f, 1);   #else    emit1(F_CALL_LFUN, f);   #endif    emit0(F_POP_VALUE);    return !(flags & DO_POP);    }    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case F_EXTERNAL:    /* Check that it is in this context */ -  if(Pike_compiler ->new_program->id == CDR(n)->u.integer.a) +  if(Pike_compiler ->new_program->id == CAR(n)->u.integer.a)    {    /* Check that it is a variable */ -  if(CDR(n)->u.integer.b != IDREF_MAGIC_THIS && -  IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.integer.b)->identifier_flags)) +  if(CAR(n)->u.integer.b != IDREF_MAGIC_THIS && +  IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.integer.b)->identifier_flags))    { -  code_expression(CAR(n), 0, "RHS"); -  emit_assign_global(CDR(n)->u.integer.b, flags & DO_POP ); +  code_expression(CDR(n), 0, "RHS"); +  emit_assign_global(CAR(n)->u.integer.b, flags & DO_POP );    break;    }    }    /* fall through */       default:    normal_assign: -  tmp1=do_docode(CDR(n),DO_LVALUE); -  if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!"); +  tmp1=do_docode(CAR(n),DO_LVALUE); +  if(do_docode(CDR(n),0)!=1) yyerror("RHS is void!");    emit0(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);    break;    }    return flags & DO_POP ? 0 : 1;    }       case F_LAND:    case F_LOR:    tmp1=alloc_label();    if(flags & DO_POP)
pike.git/src/docode.c:1660:    do_jump_when_non_zero(CAR(n), (INT32)tmp2);    ins_label(current_label->break_label);       current_switch.jumptable = prev_switch_jumptable;    POP_STATEMENT_LABEL;    BLOCK_END;    return 0;    }       case ' ': +  /* FIXME: Is this code reached? */    ret = do_docode(CAR(n),0);    return ret + do_docode(CDR(n),DO_LVALUE);       case F_FOREACH:    {    node *arr;    INT32 *prev_switch_jumptable = current_switch.jumptable;    arr=CAR(n);       if(CDR(arr) && CDR(arr)->token == ':')
pike.git/src/docode.c:1682:    /* New-style */    tmp1=do_docode(CAR(arr), DO_NOT_COPY_TOPLEVEL);    emit0(F_MAKE_ITERATOR);       if(CADR(arr))    {    do_docode(CADR(arr), DO_LVALUE);    }else{    emit0(F_CONST0);    emit0(F_CONST0); -  current_stack_depth+=2; +  modify_stack_depth(2);    }       if(CDDR(arr))    {    do_docode(CDDR(arr), DO_LVALUE);    }else{    emit0(F_CONST0);    emit0(F_CONST0); -  current_stack_depth+=2; +  modify_stack_depth(2);    }       PUSH_CLEANUP_FRAME(do_pop, 5);       PUSH_STATEMENT_LABEL;    current_switch.jumptable=0;    current_label->break_label=alloc_label();    current_label->continue_label=alloc_label();       /* Doubt it's necessary to use a label separate from
pike.git/src/docode.c:1756:    do_jump(F_BRANCH_WHEN_GE, tmp1);    /* The value is negative. replace it with zero. */    emit0(F_POP_VALUE);    emit0(F_CONST0);    low_insert_label((INT32)tmp1);    goto foreach_arg_pushed;    }    }    do_docode(arr,DO_NOT_COPY);    emit0(F_CONST0); -  current_stack_depth++; +  modify_stack_depth(1);    foreach_arg_pushed:    PUSH_CLEANUP_FRAME(do_pop, 4);       PUSH_STATEMENT_LABEL;    current_switch.jumptable=0;    current_label->break_label=alloc_label();    current_label->continue_label=alloc_label();       tmp3=do_branch(-1);    tmp1=ins_label(-1);
pike.git/src/docode.c:2134:       if (!(CAR(n) && (current_switch.type = CAR(n)->type))) {    current_switch.type = mixed_type_string;    }       current_label->break_label=alloc_label();       cases=count_cases(CDR(n));       tmp1=emit1(F_SWITCH,0); -  current_stack_depth--; +  modify_stack_depth(-1);    emit1(F_ALIGN,sizeof(INT32));       current_switch.values_on_stack=0;    current_switch.index=2;    current_switch.less_label=-1;    current_switch.greater_label=-1;    current_switch.default_label=-1;    current_switch.jumptable=xalloc(sizeof(INT32)*(cases*2+2));    jumptable=xalloc(sizeof(INT32)*(cases*2+2));   
pike.git/src/docode.c:2484:    current_label->break_label=alloc_label();       DO_CODE_BLOCK(CAR(n));       ins_label(current_label->break_label);    emit0(F_EXIT_CATCH);    POP_STATEMENT_LABEL;    current_switch.jumptable = prev_switch_jumptable;    do_branch (tmp1);    -  current_stack_depth++; +  modify_stack_depth(1);    /* Entry point called via catching_eval_instruction() after    * catching an error.    *    * NB: This is reached by subtracting ENTRY_PROLOGUE_SIZE    * from the label below.    * NB: The label must be after the entry, since it may expand to code    * that requires the entry code to have run.    */    emit0(F_ENTRY);    ins_label((INT32)tmp1);
pike.git/src/docode.c:2644:    PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;    x++;    }   #endif    emit2(F_EXTERNAL, SUBTYPEOF(n->u.sval), x);    Pike_compiler->new_program->flags |=    PROGRAM_USES_PARENT | PROGRAM_NEEDS_PARENT;    return 1;    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    default:   #ifdef PIKE_DEBUG    if((TYPEOF(n->u.sval) == T_OBJECT) &&    (n->u.sval.u.object->next == n->u.sval.u.object))    Pike_fatal("Internal error: Pointer to parent cannot be a compile time constant!\n");   #endif    tmp1=store_constant(&(n->u.sval),    !(n->tree_info & OPT_EXTERNAL_DEPEND),    n->name);    emit1(F_CONSTANT, (INT32)tmp1);
pike.git/src/docode.c:2753:    int depth=0;    for(f=Pike_compiler->compiler_frame;    f!=n->u.trampoline.frame;f=f->previous)    depth++;       emit2(F_TRAMPOLINE,n->u.trampoline.ident,depth);    return 1;    }       case F_VAL_LVAL: +  case F_FOREACH_VAL_LVAL:    ret = do_docode(CAR(n),flags);    return ret + do_docode(CDR(n), flags | DO_LVALUE);       case F_AUTO_MAP:    emit0(F_MARK);    code_expression(CAR(n), 0, "automap function");    do_encode_automap_arg_list(CDR(n),0);    emit_apply_builtin("__automap__");    return 1;   
pike.git/src/docode.c:2775:    {    do_docode(CAR(n),DO_LVALUE);    }    else    {    yyerror("[*] not supported here.\n");    emit0(F_CONST0);    }    return 1;    +  case F_TYPEOF: +  { +  struct svalue s; +  /* NB: This should only be reachable via eval_low(). +  * Typically treeopt will get rid of this node. +  */ +  SET_SVAL(s, PIKE_T_TYPE, 0, type, +  CAR(n)->type?CAR(n)->type:mixed_type_string); +  tmp1 = store_constant(&s, 0, NULL); +  emit1(F_CONSTANT, (INT32)tmp1); +  } +  return 1; +     default:    Pike_fatal("Infernal compiler error (unknown parse-tree-token %d).\n", n->token);    UNREACHABLE(return 0);    }   }      static void emit_save_locals(struct compiler_frame *f)   {    struct compilation *c = THIS_COMPILATION;    unsigned INT16 offset;
pike.git/src/docode.c:2812:    }   }      /* Used to generate code for functions. */   INT32 do_code_block(node *n, int identifier_flags)   {    struct compilation *c = THIS_COMPILATION;    struct reference *id = NULL;    INT32 entry_point;    int aggregate_cnum = -1; - #ifdef PIKE_DEBUG -  if (current_stack_depth != -4711) Pike_fatal("Reentrance in do_code_block().\n"); +  int save_stack_depth = current_stack_depth; +  int save_label_no = label_no;    current_stack_depth = 0; - #endif +        if (Pike_compiler->compiler_frame->current_function_number >= 0) {    id = Pike_compiler->new_program->identifier_references +    Pike_compiler->compiler_frame->current_function_number;    }       init_bytecode();    label_no=1;       /* NOTE: This is no ordinary label... */
pike.git/src/docode.c:2918:    Pike_compiler->compiler_frame->max_number_of_locals);    }    if (Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED) {    emit_save_locals(Pike_compiler->compiler_frame);    }       DO_CODE_BLOCK(n);    }    entry_point = assemble(1);    - #ifdef PIKE_DEBUG -  current_stack_depth = -4711; - #endif +  current_stack_depth = save_stack_depth; +  label_no = save_label_no;    return entry_point;   }      /* Used by eval_low() to build code for constant expressions. */   INT32 docode(node *n)   {    INT32 entry_point;    int label_no_save = label_no;    struct byte_buffer instrbuf_save = instrbuf;    int stack_depth_save = current_stack_depth;