pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:671: Inside #if defined(PIKE_DEBUG)
   }    if (num_args != expected_args)    Pike_fatal ("Wrong number of args to o_range opcode. Expected %d, got %d.\n",    expected_args, num_args);    }   #endif       emit1 (F_RANGE, bound_types);   }    + static void emit_global( int n ) + { +  struct compilation *c = THIS_COMPILATION; +  struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); +  struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref); +  if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) +  && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) +  && IDENTIFIER_IS_VARIABLE(id->identifier_flags) +  && !ref->inherit_offset +  && id->run_time_type == PIKE_T_MIXED ) +  { +  /* fprintf( stderr, "private global %d\n", (INT32)id->func.offset ); */ +  emit1(F_PRIVATE_GLOBAL, id->func.offset); +  } +  else +  emit1(F_GLOBAL, n); + } +  + static void emit_assign_global( int n, int and_pop ) + { +  struct compilation *c = THIS_COMPILATION; +  struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); +  struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref); +  +  if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) +  && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) +  && !ref->inherit_offset +  && id->run_time_type == PIKE_T_MIXED ) +  { +  /* fprintf( stderr, "assign private global and pop %d\n", */ +  /* (INT32)id->func.offset ); */ +  emit1((and_pop?F_ASSIGN_PRIVATE_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_GLOBAL), +  id->func.offset); +  } +  else +  { +  emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n); +  } + } +    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:719:       /* FIXME: Make special case for F_EXTERNAL */    case F_IDENTIFIER:    if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program,    var->u.id.number)->identifier_flags))    {    yyerror("Cannot assign functions or constants.\n");    }else{    code_expression(val, 0, "RHS");    emit_multi_assign(vals, vars, no+1); -  emit1(F_ASSIGN_GLOBAL_AND_POP, var->u.id.number); +  emit_assign_global( var->u.id.number, 1 );    }    break;       case F_GET_SET:    {    /* Check for the setter function. */    struct program_state *state = Pike_compiler;    int program_id = var->u.integer.a;    int level = 0;    while (state && (state->new_program->id != program_id)) {
pike.git/src/docode.c:778:    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); -  emit1(F_ASSIGN_GLOBAL_AND_POP, var->u.integer.b); +  emit_assign_global( var->u.integer.b, 1 );    break;    }    }    /* fall through */       default:    normal_assign:    do_docode(var, DO_LVALUE);    if(do_docode(val, 0) != 1) yyerror("RHS is void!");    emit_multi_assign(vals, vars, no+1);
pike.git/src/docode.c:984:    struct svalue *s = &state->new_program->    constants[id->func.const_info.offset].sval;    if (TYPEOF(*s) == T_PROGRAM &&    s->u.program->flags & PROGRAM_USES_PARENT) {    /* Program using parent. Convert to an LFUN. */    emit1(F_LFUN, n->u.integer.b);    } else {    emit1(F_CONSTANT, id->func.const_info.offset);    }    }else{ -  emit1(F_GLOBAL, n->u.integer.b); +  emit_global( n->u.integer.b );    }    }    }    return 1;       case F_THIS:    {    int level = 0;    struct program_state *state = Pike_compiler;    int inh = n->u.integer.b;
pike.git/src/docode.c:1264:    case F_LSH:    case F_RSH:    case F_ADD:    case F_MOD:    case F_SUBTRACT:    case F_DIVIDE:    case F_MULTIPLY:    if(node_is_eq(CDR(n),CAAR(n)))    {    int num_args; -  tmp1=do_docode(CDR(n),DO_LVALUE); +  /* 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))    { -  +  do_docode(CDR(n),DO_LVALUE);    num_args = do_docode(CDAR(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);    }       if (CAR (n)->token == F_RANGE)    emit_range (CAR (n) DO_IF_DEBUG (COMMA num_args));    else    emit0(CAR(n)->token);       emit0(n->token);
pike.git/src/docode.c:1307:    (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);    if (args) {    node **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);    }    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;    case F_LOCAL:    if(CDR(n)->u.integer.a >=    find_local_frame(CDR(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 (CDR(n)->node_info & OPT_ASSIGNMENT) {    /* Initialize. */    emit0(F_CONST0);
pike.git/src/docode.c:1355:    CDR(n)->u.integer.a );    break;       /* FIXME: Make special case for F_EXTERNAL */    case F_IDENTIFIER:    if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.id.number)->identifier_flags))    {    yyerror("Cannot assign functions or constants.\n");    }else{    code_expression(CAR(n), 0, "RHS"); -  emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL, -  CDR(n)->u.id.number); +  emit_assign_global( CDR(n)->u.id.number, flags & DO_POP );    }    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)) {
pike.git/src/docode.c:1428:    /* FALL_THROUGH */    case F_EXTERNAL:    /* Check that it is in this context */    if(Pike_compiler ->new_program->id == CDR(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))    {    code_expression(CAR(n), 0, "RHS"); -  emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL, -  CDR(n)->u.integer.b); +  emit_assign_global(CDR(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!");    emit0(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
pike.git/src/docode.c:2763:    if(flags & WANT_LVALUE)    {    yyerror("Cannot assign functions.\n");    }else{    if (id->identifier_flags & IDENTIFIER_HAS_BODY)    /* Only use this opcode when it's certain that the result    * can't zero, i.e. when we know the function isn't just a    * prototype. */    emit1(F_LFUN,n->u.id.number);    else -  emit1(F_GLOBAL,n->u.id.number); +  emit_global(n->u.id.number);    }    }else{    if(flags & WANT_LVALUE)    {    emit1(F_GLOBAL_LVALUE,n->u.id.number);    return 2;    }else{ -  emit1(F_GLOBAL,n->u.id.number); +  emit_global(n->u.id.number);    }    }    return 1;    }       case F_VAL_LVAL:    ret = do_docode(CAR(n),flags);    return ret + do_docode(CDR(n), flags | DO_LVALUE);       case F_AUTO_MAP: