pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:736:    else    emit2((and_pop?F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_TYPED_GLOBAL),    id->func.offset, id->run_time_type);    }    else    {    emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n);    }   }    + static int emit_ltosval_call_and_assign( node *lval, node *func, node *args ) + { +  struct compilation *c = THIS_COMPILATION; +  node **arg; +  int no = 0; +  int tmp1=store_constant(&func->u.sval, +  !(func->tree_info & OPT_EXTERNAL_DEPEND), +  func->name); +  +  + #ifdef PIKE_DEBUG +  arg = my_get_arg(&args,0); +  if( !node_is_eq(*arg,lval) ) +  Pike_fatal("lval should be the same as arg1, or this will not work.\n"); + #endif +  do_docode(lval, DO_LVALUE); +  emit0(F_MARK); +  emit0(F_CONST0); +  PUSH_CLEANUP_FRAME(do_pop_mark, 0); +  while ((arg = my_get_arg(&args, ++no)) && *arg) { +  do_docode(*arg, 0); +  } +  emit1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, DO_NOT_WARN((INT32)tmp1)); +  POP_AND_DONT_CLEANUP; +  return 1; + } +    static void emit_multi_assign(node *vals, node *vars, int no)   {    struct compilation *c = THIS_COMPILATION;    node *var;    node *val;    node **valp = my_get_arg(&vals, no);       if (!vars && (!valp || !*valp)) return;    if (!(vars && valp && (val = *valp))) {    yyerror("Argument count mismatch for multi-assignment.\n");
pike.git/src/docode.c:1171:    emit1(F_ARRAY_LVALUE, DO_NOT_WARN((INT32)(tmp1>>1)));    emit0(F_MARK);    PUSH_CLEANUP_FRAME(do_pop_mark, 0);    do_docode(CAR(n), 0);    emit_apply_builtin("aggregate");    POP_AND_DONT_CLEANUP;    emit0(F_ASSIGN);    return 1;    }    +  { +  case F_ASSIGN_SELF: +  /* a special case, we know we can not really optimize. +  car: softcast(efuncall(function,args(2))) +  */ +  /* node *args=CAADR(n), *func = CAAAR(n); */ +  if( CDR(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) ); +     case F_ASSIGN: -  +  +  /* if assign self is 1 we know this: +  car(n) = lvalue +  cdr(n)= softcast(apply(efun, arglist(car(n),one more arg))) +  +  We only want to evaluate car(n) once. +  */    if( CDR(n)->token == F_AUTO_MAP_MARKER )    {    int depth = 0;    node *lval = CDR(n);    while( lval->token == F_AUTO_MAP_MARKER )    {    lval = CAR(lval);    depth++;    }    do_docode(lval,0); /* note: not lvalue */
pike.git/src/docode.c:1195:    if( CAR(n)->token == F_AUTO_MAP_MARKER ||    CAR(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))))    {    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)    {    case F_RANGE:    if(node_is_eq(CDR(n),CAAR(n)))    {
pike.git/src/docode.c:1248:    emit0(n->token);    return n->token==F_ASSIGN; /* So when is this false? /mast */    }    case F_APPLY:    if ((CAAR(n)->token == F_CONSTANT) &&    (TYPEOF(CAAR(n)->u.sval) == T_FUNCTION) &&    (SUBTYPEOF(CAAR(n)->u.sval) == FUNCTION_BUILTIN) &&    (CAAR(n)->u.sval.u.efun->function != f_map) &&    (CAAR(n)->u.sval.u.efun->function != f_filter)) {    /* efuns typically don't access object variables. */ -  node *args = CDAR(n); +  node *args = CDAR(n), **arg;    if (args && count_args(args) > 1)    { -  node **arg = my_get_arg(&args, 0); +  arg = my_get_arg(&args, 0);    if (arg && node_is_eq(CDR(n), *arg) &&    !(args->tree_info & OPT_ASSIGNMENT)) {    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))    {    /* First arg is the lvalue. -  * +     * We optimize this to allow for destructive operations.    */ -  int no = 0; -  tmp1 = do_docode(CDR(n), DO_LVALUE); -  emit0(F_MARK_AND_CONST0); -  PUSH_CLEANUP_FRAME(do_pop_mark, 0); -  while ((arg = my_get_arg(&args, ++no)) && *arg) { -  do_docode(*arg, 0); +  return emit_ltosval_call_and_assign( CDR(n), CAAR(n), CDAR(n) );    } -  tmp1=store_constant(&CAAR(n)->u.sval, -  !(CAAR(n)->tree_info & OPT_EXTERNAL_DEPEND), -  CAAR(n)->name); -  emit1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, DO_NOT_WARN((INT32)tmp1)); -  POP_AND_DONT_CLEANUP; -  return 1; +     }    }    } -  } +     /* FALL_THROUGH */    default:    do_not_suboptimize_assign:    switch(CDR(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 );    break;
pike.git/src/docode.c:1308:    if (CDR(n)->node_info & OPT_ASSIGNMENT) {    /* Initialize. */    emit0(F_CONST0);    emit1(F_ASSIGN_LOCAL_AND_POP, CDR(n)->u.integer.a);    }    code_expression(CAR(n), 0, "RHS");    emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,    CDR(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 level = 0;    while (state && (state->new_program->id != program_id)) {    state = state->previous;    level++;    }
pike.git/src/docode.c:1392:       default:    normal_assign:    tmp1=do_docode(CDR(n),DO_LVALUE);    if(do_docode(CAR(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)    {    do_cond_jump(CAR(n), DO_NOT_WARN((INT32)tmp1), n->token == F_LOR, DO_POP);    DO_CODE_BLOCK(CDR(n));    low_insert_label( DO_NOT_WARN((INT32)tmp1));    return 0;