pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: docode.c,v 1.67 2000/03/30 08:43:07 hubbe Exp $"); + RCSID("$Id: docode.c,v 1.68 2000/04/20 02:41:44 hubbe Exp $");   #include "las.h"   #include "program.h"   #include "language.h"   #include "pike_types.h"   #include "stralloc.h"   #include "interpret.h"   #include "constants.h"   #include "array.h"   #include "pike_macros.h"   #include "error.h"
pike.git/src/docode.c:48:   }      int store_linenumbers=1;   static int label_no=0;      int alloc_label(void) { return ++label_no; }      int do_jump(int token,INT32 lbl)   {    if(lbl==-1) lbl=alloc_label(); -  emit(token, lbl); +  emit1(token, lbl);    return lbl;   }      #define ins_label(L) do_jump(F_LABEL, L)      void do_pop(int x)   {    switch(x)    {    case 0: return; -  case 1: emit2(F_POP_VALUE); break; -  default: emit(F_POP_N_ELEMS,x); break; +  case 1: emit0(F_POP_VALUE); break; +  default: emit1(F_POP_N_ELEMS,x); break;    }   }      #define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP | DO_DEFER_POP))      int do_docode(node *n,INT16 flags)   {    int i;    int save_current_line=lex.current_line;    if(!n) return 0;
pike.git/src/docode.c:123:       switch(n->token)    {    case F_LAND:    case F_LOR:    if(iftrue == (n->token==F_LAND))    {    int tmp=alloc_label();    do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP);    do_cond_jump(CDR(n), label, iftrue, flags); -  emit(F_LABEL,tmp); +  emit1(F_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;       case F_NOT:
pike.git/src/docode.c:205:    INT32 tmp1,tmp2,tmp3;       if(!n) return 0;       if(flags & DO_LVALUE)    {    switch(n->token)    {    default:    yyerror("Illegal lvalue."); -  emit(F_NUMBER,0); -  emit(F_NUMBER,0); +  emit1(F_NUMBER,0); +  emit1(F_NUMBER,0);    return 2;       case F_ARRAY_LVALUE:    case F_LVALUE_LIST:    case F_LOCAL:    case F_GLOBAL:    case F_IDENTIFIER:    case F_INDEX:    case F_ARROW:    case F_ARG_LIST:
pike.git/src/docode.c:239:    }       /* Stack check */    {    long x_= ((char *)&x_) + STACK_DIRECTION * (32768) - stack_top ;    x_*=STACK_DIRECTION;    if(x_>0)    {    yyerror("Too deep recursion in compiler. (please report this)");    -  emit(F_NUMBER,0); +  emit1(F_NUMBER,0);    if(flags & DO_LVALUE)    { -  emit(F_NUMBER,0); +  emit1(F_NUMBER,0);    return 2;    }    return 1;    }    }       switch(n->token)    {    case F_MAGIC_INDEX:    case F_MAGIC_SET_INDEX: -  emit(F_LDA, n->u.node.a->u.sval.u.integer); -  emit(n->token, n->u.node.b->u.sval.u.integer); +  emit2(n->token, +  n->u.node.b->u.sval.u.integer, +  n->u.node.a->u.sval.u.integer);    return 1;       case F_EXTERNAL: -  emit(F_LDA, n->u.integer.a); +     if(flags & WANT_LVALUE)    { -  emit(F_EXTERNAL_LVALUE, n->u.integer.b); +  emit2(F_EXTERNAL_LVALUE, n->u.integer.b,n->u.integer.a);    return 2;    }else{ -  emit(F_EXTERNAL, n->u.integer.b); +  emit2(F_EXTERNAL, n->u.integer.b,n->u.integer.a);    return 1;    }    break;       case F_UNDEFINED:    yyerror("Undefined identifier"); -  emit(F_NUMBER,0); +  emit1(F_NUMBER,0);    return 1;       case F_PUSH_ARRAY:    code_expression(CAR(n), 0, "`@"); -  emit2(F_PUSH_ARRAY); +  emit0(F_PUSH_ARRAY);    return -0x7ffffff;       case '?':    {    INT32 *prev_switch_jumptable = current_switch_jumptable;    int adroppings , bdroppings;    current_switch_jumptable=0;          if(!CDDR(n))    {    tmp1=alloc_label();    do_jump_when_zero(CAR(n), tmp1);    DO_CODE_BLOCK(CADR(n)); -  emit(F_LABEL, tmp1); +  emit1(F_LABEL, tmp1);    current_switch_jumptable = prev_switch_jumptable;    return 0;    }       if(!CADR(n))    {    tmp1=alloc_label();    do_jump_when_non_zero(CAR(n), tmp1);    DO_CODE_BLOCK(CDDR(n)); -  emit(F_LABEL,tmp1); +  emit1(F_LABEL,tmp1);    current_switch_jumptable = prev_switch_jumptable;    return 0;    }       tmp1=alloc_label();    do_jump_when_zero(CAR(n),tmp1);       adroppings=do_docode(CADR(n), flags); -  tmp3=emit(F_POP_N_ELEMS,0); +  tmp3=emit1(F_POP_N_ELEMS,0);       /* Else */    tmp2=do_jump(F_BRANCH,-1); -  emit(F_LABEL, tmp1); +  emit1(F_LABEL, tmp1);       bdroppings=do_docode(CDDR(n), flags);    if(adroppings < bdroppings)    {    do_pop(bdroppings - adroppings);    }       if(adroppings > bdroppings)    {    update_arg(tmp3,adroppings-bdroppings);    adroppings=bdroppings;    }    -  emit(F_LABEL, tmp2); +  emit1(F_LABEL, tmp2);       current_switch_jumptable = prev_switch_jumptable;    return adroppings;    }       case F_AND_EQ:    case F_OR_EQ:    case F_XOR_EQ:    case F_LSH_EQ:    case F_RSH_EQ:
pike.git/src/docode.c:355: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(tmp1 != 2)    fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n");   #endif       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))    {    code_expression(CDR(n), 0, "assignment"); -  emit2(F_LTOSVAL2); +  emit0(F_LTOSVAL2);    }else{ -  emit2(F_LTOSVAL); +  emit0(F_LTOSVAL);    code_expression(CDR(n), 0, "assignment");    }          switch(n->token)    { -  case F_ADD_EQ: emit2(F_ADD); break; -  case F_AND_EQ: emit2(F_AND); break; -  case F_OR_EQ: emit2(F_OR); break; -  case F_XOR_EQ: emit2(F_XOR); break; -  case F_LSH_EQ: emit2(F_LSH); break; -  case F_RSH_EQ: emit2(F_RSH); break; -  case F_SUB_EQ: emit2(F_SUBTRACT); break; -  case F_MULT_EQ:emit2(F_MULTIPLY);break; -  case F_MOD_EQ: emit2(F_MOD); break; -  case F_DIV_EQ: emit2(F_DIVIDE); break; +  case F_ADD_EQ: emit0(F_ADD); break; +  case F_AND_EQ: emit0(F_AND); break; +  case F_OR_EQ: emit0(F_OR); break; +  case F_XOR_EQ: emit0(F_XOR); break; +  case F_LSH_EQ: emit0(F_LSH); break; +  case F_RSH_EQ: emit0(F_RSH); break; +  case F_SUB_EQ: emit0(F_SUBTRACT); break; +  case F_MULT_EQ:emit0(F_MULTIPLY);break; +  case F_MOD_EQ: emit0(F_MOD); break; +  case F_DIV_EQ: emit0(F_DIVIDE); break;    }       if(flags & DO_POP)    { -  emit2(F_ASSIGN_AND_POP); +  emit0(F_ASSIGN_AND_POP);    return 0;    }else{ -  emit2(F_ASSIGN); +  emit0(F_ASSIGN);    return 1;    }       case F_ASSIGN:    switch(CAR(n)->token)    {    case F_AND:    case F_OR:    case F_XOR:    case F_LSH:
pike.git/src/docode.c:405:    case F_SUBTRACT:    case F_DIVIDE:    case F_MULTIPLY:    if(node_is_eq(CDR(n),CAAR(n)))    {    tmp1=do_docode(CDR(n),DO_LVALUE);    if(match_types(CDR(n)->type,array_type_string) ||    match_types(CDR(n)->type,string_type_string))    {    code_expression(CDAR(n), 0, "binary operand"); -  emit2(F_LTOSVAL2); +  emit0(F_LTOSVAL2);    }else{ -  emit2(F_LTOSVAL); +  emit0(F_LTOSVAL);    code_expression(CDAR(n), 0, "binary operand");    }    -  emit2(CAR(n)->token); +  emit0(CAR(n)->token);    -  emit2(n->token); +  emit0(n->token);    return n->token==F_ASSIGN;    }       default:    switch(CDR(n)->token)    {    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;       code_expression(CAR(n), 0, "RHS"); -  emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL, +  emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,    CDR(n)->u.integer.a );    break;       case F_IDENTIFIER:    if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(new_program, CDR(n)->u.id.number)->identifier_flags))    {    yyerror("Cannot assign functions or constants.\n");    }else{    code_expression(CAR(n), 0, "RHS"); -  emit(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL, +  emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,    CDR(n)->u.id.number);    }    break;       default:    normal_assign:    tmp1=do_docode(CDR(n),DO_LVALUE);    if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!"); -  emit2(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN); +  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();    do_cond_jump(CAR(n), tmp1, n->token == F_LOR, 0);    code_expression(CDR(n), flags, n->token == F_LOR ? "||" : "&&"); -  emit(F_LABEL,tmp1); +  emit1(F_LABEL,tmp1);    return 1;       case F_EQ:    case F_NE:    case F_ADD:    case F_LT:    case F_LE:    case F_GT:    case F_GE:    case F_SUBTRACT:
pike.git/src/docode.c:486:    case F_AND:    case F_NOT:    case F_COMPL:    case F_NEGATE:    fatal("Optimizer error.\n");       case F_RANGE:    tmp1=do_docode(CAR(n),DO_NOT_COPY);    if(do_docode(CDR(n),DO_NOT_COPY)!=2)    fatal("Compiler internal error (at %ld).\n",(long)lex.current_line); -  emit2(n->token); +  emit0(n->token);    return tmp1;       case F_INC:    case F_POST_INC:    tmp1=do_docode(CAR(n),DO_LVALUE);   #ifdef PIKE_DEBUG    if(tmp1 != 2)    fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");   #endif       if(flags & DO_POP)    { -  emit2(F_INC_AND_POP); +  emit0(F_INC_AND_POP);    return 0;    }else{ -  emit2(n->token); +  emit0(n->token);    return 1;    }       case F_DEC:    case F_POST_DEC:    tmp1=do_docode(CAR(n),DO_LVALUE);   #ifdef PIKE_DEBUG    if(tmp1 != 2)    fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n");   #endif    if(flags & DO_POP)    { -  emit2(F_DEC_AND_POP); +  emit0(F_DEC_AND_POP);    return 0;    }else{ -  emit2(n->token); +  emit0(n->token);    return 1;    }       case F_FOR:    {    INT32 *prev_switch_jumptable = current_switch_jumptable;    INT32 break_save = current_break;    INT32 continue_save = current_continue;       current_switch_jumptable=0;
pike.git/src/docode.c:582:    a2[0]->u.sval.type==T_INT &&    a2[0]->u.sval.type==0x7fffffff &&    a1[0]->type == int_type_string)    {    tmp2=do_docode(CAR(arr),DO_NOT_COPY);    do_docode(*a1,DO_NOT_COPY);    goto foreach_arg_pushed;    }    }    tmp2=do_docode(CAR(n),DO_NOT_COPY); -  emit2(F_CONST0); +  emit0(F_CONST0);       foreach_arg_pushed:   #ifdef PIKE_DEBUG    /* This is really ugly because there is always a chance that the bug    * will disappear when new instructions are added to the code, but    * think it is worth it.    */    if(d_flag) -  emit2(F_MARK); +  emit0(F_MARK);   #endif    tmp3=do_jump(F_BRANCH,-1);    tmp1=ins_label(-1);    DO_CODE_BLOCK(CDR(n));    ins_label(current_continue); -  emit(F_LABEL,tmp3); +  emit1(F_LABEL,tmp3);    do_jump(n->token,tmp1);    ins_label(current_break);      #ifdef PIKE_DEBUG    if(d_flag) -  emit2(F_POP_MARK); +  emit0(F_POP_MARK);   #endif       current_switch_jumptable = prev_switch_jumptable;    current_break=break_save;    current_continue=continue_save;    do_pop(4);    return 0;    }       case F_INC_NEQ_LOOP:
pike.git/src/docode.c:633:    current_break=alloc_label();    current_continue=alloc_label();       tmp2=do_docode(CAR(n),0);   #ifdef PIKE_DEBUG    /* This is really ugly because there is always a chance that the bug    * will disappear when new instructions are added to the code, but    * think it is worth it.    */    if(d_flag) -  emit2(F_MARK); +  emit0(F_MARK);   #endif    tmp3=do_jump(F_BRANCH,-1);    tmp1=ins_label(-1);       DO_CODE_BLOCK(CDR(n));    ins_label(current_continue); -  emit(F_LABEL,tmp3); +  emit1(F_LABEL,tmp3);    do_jump(n->token,tmp1);    ins_label(current_break);   #ifdef PIKE_DEBUG    if(d_flag) -  emit2(F_POP_MARK); +  emit0(F_POP_MARK);   #endif       current_switch_jumptable = prev_switch_jumptable;    current_break=break_save;    current_continue=continue_save;    do_pop(3);    return 0;    }       case F_DO:
pike.git/src/docode.c:690:    return 0;    }       case F_CAST:    if(n->type==void_type_string)    {    DO_CODE_BLOCK(CAR(n));    return 0;    }    tmp1=store_prog_string(n->type); -  emit(F_STRING,tmp1); +  emit1(F_STRING,tmp1);       tmp1=do_docode(CAR(n),0); -  if(!tmp1) { emit2(F_CONST0); tmp1=1; } +  if(!tmp1) { emit0(F_CONST0); tmp1=1; }    if(tmp1>1) do_pop(tmp1-1);    -  emit2(F_CAST); +  emit0(F_CAST);    return 1;       case F_SOFT_CAST:    if (runtime_options & RUNTIME_CHECK_TYPES) {    tmp1 = store_prog_string(n->type); -  emit(F_STRING, tmp1); +  emit1(F_STRING, tmp1);    tmp1 = do_docode(CAR(n), 0); -  if (!tmp1) { emit2(F_CONST0); tmp1 = 1; } +  if (!tmp1) { emit0(F_CONST0); tmp1 = 1; }    if (tmp1 > 1) do_pop(tmp1 - 1); -  emit2(F_SOFT_CAST); +  emit0(F_SOFT_CAST);    return 1;    }    tmp1 = do_docode(CAR(n), flags);    if (tmp1 > 1) do_pop(tmp1 - 1);    return !!tmp1;       case F_APPLY:    if(CAR(n)->token == F_CONSTANT)    {    if(CAR(n)->u.sval.type == T_FUNCTION)    {    if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN) /* driver fun? */    {    if(!CAR(n)->u.sval.u.efun->docode ||    !CAR(n)->u.sval.u.efun->docode(n))    { -  emit2(F_MARK); +  emit0(F_MARK);    do_docode(CDR(n),0);    tmp1=store_constant(& CAR(n)->u.sval,    !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),    CAR(n)->name); -  emit(F_APPLY,tmp1); +  emit1(F_APPLY,tmp1);    }    if(n->type == void_type_string)    return 0;       return 1;    }else{    if(CAR(n)->u.sval.u.object == fake_object)    { -  emit2(F_MARK); +  emit0(F_MARK);    do_docode(CDR(n),0); -  emit(F_CALL_LFUN, CAR(n)->u.sval.subtype); +  emit1(F_CALL_LFUN, CAR(n)->u.sval.subtype);    return 1;    }    }    }    -  emit2(F_MARK); +  emit0(F_MARK);    do_docode(CDR(n),0);    tmp1=store_constant(& CAR(n)->u.sval,    !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),    CAR(n)->name); -  emit(F_APPLY,tmp1); +  emit1(F_APPLY,tmp1);       return 1;    }    else if(CAR(n)->token == F_IDENTIFIER &&    IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, CAR(n)->u.id.number)->identifier_flags))    { -  emit2(F_MARK); +  emit0(F_MARK);    do_docode(CDR(n),0); -  emit(F_CALL_LFUN, CAR(n)->u.id.number); +  emit1(F_CALL_LFUN, CAR(n)->u.id.number);    return 1;    }    else    {    struct pike_string *tmp;    struct efun *fun;    node *foo;    -  emit2(F_MARK); +  emit0(F_MARK);    do_docode(CAR(n),0);    do_docode(CDR(n),0);       tmp=findstring("call_function");    if(!tmp) yyerror("No call_function efun.");    foo=find_module_identifier(tmp,0);    if(!foo || !foo->token==F_CONSTANT)    {    yyerror("No call_function efun.");    }else{    if(foo->u.sval.type == T_FUNCTION &&    foo->u.sval.subtype == FUNCTION_BUILTIN &&    foo->u.sval.u.efun->function == f_call_function)    { -  emit2(F_CALL_FUNCTION); +  emit0(F_CALL_FUNCTION);    }else{    /* We might want to put "predef::"+foo->name here /Hubbe */    tmp1=store_constant(& foo->u.sval, 1, foo->name); -  emit(F_APPLY, tmp1); +  emit1(F_APPLY, tmp1);    }    }    free_node(foo);    return 1;    }       case F_ARG_LIST:    case F_COMMA_EXPR:    tmp1=do_docode(CAR(n),flags & ~WANT_LVALUE);    tmp1+=do_docode(CDR(n),flags);
pike.git/src/docode.c:839:    fatal("Internal compiler error, time to panic\n");       if (!(CAR(n) && (current_switch_type = CAR(n)->type))) {    current_switch_type = mixed_type_string;    }       current_break=alloc_label();       cases=count_cases(CDR(n));    -  tmp1=emit(F_SWITCH,0); -  emit(F_ALIGN,sizeof(INT32)); +  tmp1=emit1(F_SWITCH,0); +  emit1(F_ALIGN,sizeof(INT32));       current_switch_values_on_stack=0;    current_switch_case=1;    current_switch_default=-1;    current_switch_jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2));    jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+2));       for(e=1; e<cases*2+2; e++)    { -  jumptable[e]=emit(F_POINTER, 0); +  jumptable[e]=emit1(F_POINTER, 0);    current_switch_jumptable[e]=-1;    }       current_switch_jumptable[current_switch_case++]=-1;       DO_CODE_BLOCK(CDR(n));      #ifdef PIKE_DEBUG    if(sp-save_sp != cases)    fatal("Count cases is wrong!\n");
pike.git/src/docode.c:911:    pop_stack();    free((char *)jumptable);    free((char *)current_switch_jumptable);       current_switch_jumptable = prev_switch_jumptable;    current_switch_default = prev_switch_default;    current_switch_case = prev_switch_case;    current_switch_values_on_stack = prev_switch_values_on_stack;    current_switch_type = prev_switch_type;    -  emit(F_LABEL, current_break); +  emit1(F_LABEL, current_break);       current_break=break_save;   #ifdef PIKE_DEBUG    if(recoveries && sp-evaluator_stack < recoveries->sp)    fatal("Stack error after F_SWITCH (underflow)\n");   #endif    return 0;    }       case F_CASE:
pike.git/src/docode.c:1036:    if(current_continue == -1)    {    yyerror("continue outside loop or switch.");    }else{    do_jump(F_BRANCH, current_continue);    }    return 0;       case F_RETURN:    do_docode(CAR(n),0); -  emit2(F_RETURN); +  emit0(F_RETURN);    return 0;       case F_SSCANF:    tmp1=do_docode(CAR(n),DO_NOT_COPY);    tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE); -  emit(F_SSCANF,tmp1+tmp2); +  emit1(F_SSCANF,tmp1+tmp2);    return 1;       case F_CATCH:    {    INT32 break_save = current_break;    INT32 continue_save = current_continue;    INT32 *prev_switch_jumptable = current_switch_jumptable;       current_switch_jumptable=0;    current_break=alloc_label();    current_continue=alloc_label();       tmp1=do_jump(F_CATCH,-1);    DO_CODE_BLOCK(CAR(n));    ins_label(current_continue);    ins_label(current_break); -  emit2(F_THROW_ZERO); +  emit0(F_THROW_ZERO);    ins_label(tmp1);       current_break=break_save;    current_continue=continue_save;    current_switch_jumptable = prev_switch_jumptable;    return 1;    }       case F_LVALUE_LIST:    return do_docode(CAR(n),DO_LVALUE)+do_docode(CDR(n),DO_LVALUE);       case F_ARRAY_LVALUE:    tmp1=do_docode(CAR(n),DO_LVALUE);   #ifdef PIKE_DEBUG    if(tmp1 & 1)    fatal("Very internal compiler error.\n");   #endif -  emit(F_ARRAY_LVALUE, tmp1>>1); +  emit1(F_ARRAY_LVALUE, tmp1>>1);    return 2;       case F_ARROW:    if(CDR(n)->token != F_CONSTANT || CDR(n)->u.sval.type!=T_STRING)    fatal("Bugg in F_ARROW, index not string.");    if(flags & WANT_LVALUE)    {    /* FIXME!!!! ??? I wonder what needs fixing... /Hubbe */    tmp1=do_docode(CAR(n), 0); -  emit(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string)); +  emit1(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string));    return 2;    }else{    tmp1=do_docode(CAR(n), DO_NOT_COPY); -  emit(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string)); +  emit1(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string));    if(!(flags & DO_NOT_COPY))    {    while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);    if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND)) -  emit2(F_COPY_VALUE); +  emit0(F_COPY_VALUE);    }    }    return tmp1;       case F_INDEX:    if(flags & WANT_LVALUE)    {    int mklval=CAR(n) && match_types(CAR(n)->type, string_type_string);    tmp1=do_docode(CAR(n),    mklval ? DO_LVALUE_IF_POSSIBLE : 0);    if(tmp1==2)    {   #ifdef PIKE_DEBUG    if(!mklval)    fatal("Unwanted lvalue!\n");   #endif -  emit2(F_INDIRECT); +  emit0(F_INDIRECT);    }       if(do_docode(CDR(n),0) != 1)    fatal("Internal compiler error, please report this (1).");    if(CDR(n)->token != F_CONSTANT &&    match_types(CDR(n)->type, string_type_string)) -  emit2(F_CLEAR_STRING_SUBTYPE); +  emit0(F_CLEAR_STRING_SUBTYPE);    return 2;    }else{    tmp1=do_docode(CAR(n), DO_NOT_COPY);       code_expression(CDR(n), DO_NOT_COPY, "index");    if(CDR(n)->token != F_CONSTANT &&    match_types(CDR(n)->type, string_type_string)) -  emit2(F_CLEAR_STRING_SUBTYPE); +  emit0(F_CLEAR_STRING_SUBTYPE);    -  emit2(F_INDEX); +  emit0(F_INDEX);       if(!(flags & DO_NOT_COPY))    {    while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);    if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND)) -  emit2(F_COPY_VALUE); +  emit0(F_COPY_VALUE);    }    }    return tmp1;       case F_CONSTANT:    switch(n->u.sval.type)    {    case T_INT:    if(!n->u.sval.u.integer && n->u.sval.subtype==NUMBER_UNDEFINED)    { -  emit2(F_UNDEFINED); +  emit0(F_UNDEFINED);    }else{ -  emit(F_NUMBER,n->u.sval.u.integer); +  emit1(F_NUMBER,n->u.sval.u.integer);    }    return 1;       case T_STRING:    tmp1=store_prog_string(n->u.sval.u.string); -  emit(F_STRING,tmp1); +  emit1(F_STRING,tmp1);    return 1;       case T_FUNCTION:    if(n->u.sval.subtype!=FUNCTION_BUILTIN)    {    if(n->u.sval.u.object == fake_object)    { -  emit(F_LFUN,n->u.sval.subtype); +  emit1(F_LFUN,n->u.sval.subtype);    return 1;    }       if(n->u.sval.u.object->next == n->u.sval.u.object)    {    int x=0;    struct object *o;       for(o=fake_object->parent;o!=n->u.sval.u.object;o=o->parent)    x++; -  emit(F_LDA, x); -  emit(F_EXTERNAL, n->u.sval.subtype); +  emit2(F_EXTERNAL, n->u.sval.subtype,x);    new_program->flags |= PROGRAM_USES_PARENT;    return 1;    }    }      #ifdef PIKE_DEBUG    case T_OBJECT:    if(n->u.sval.u.object->next == n->u.sval.u.object)    fatal("Internal error: Pointer to parent cannot be a compile time constant!\n");   #endif       default:    tmp1=store_constant(&(n->u.sval),    !(n->tree_info & OPT_EXTERNAL_DEPEND),    n->name); -  emit(F_CONSTANT,tmp1); +  emit1(F_CONSTANT,tmp1);    return 1;       case T_ARRAY:    case T_MAPPING:    case T_MULTISET:    tmp1=store_constant(&(n->u.sval),    !(n->tree_info & OPT_EXTERNAL_DEPEND),    n->name); -  emit(F_CONSTANT,tmp1); +  emit1(F_CONSTANT,tmp1);       /* copy now or later ? */    if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND)) -  emit2(F_COPY_VALUE); +  emit0(F_COPY_VALUE);    return 1;       }       case F_LOCAL:    if(n->u.integer.a >=    find_local_frame(n->u.integer.b)->max_number_of_locals)    yyerror("Illegal to use local variable here.");       if(n->u.integer.b)    { -  emit(F_LDA,n->u.integer.b); +     if(flags & WANT_LVALUE)    { -  emit(F_LEXICAL_LOCAL_LVALUE,n->u.id.number); +  emit2(F_LEXICAL_LOCAL_LVALUE,n->u.id.number,n->u.integer.b);    return 2;    }else{ -  emit(F_LEXICAL_LOCAL,n->u.id.number); +  emit2(F_LEXICAL_LOCAL,n->u.id.number,n->u.integer.b);    return 1;    }    }else{    if(flags & WANT_LVALUE)    { -  emit(F_LOCAL_LVALUE,n->u.id.number); +  emit1(F_LOCAL_LVALUE,n->u.id.number);    return 2;    }else{ -  emit(F_LOCAL,n->u.id.number); +  emit1(F_LOCAL,n->u.id.number);    return 1;    }    }       case F_TRAMPOLINE: -  emit(F_TRAMPOLINE,n->u.id.number); +  emit1(F_TRAMPOLINE,n->u.id.number);    return 1;       case F_IDENTIFIER:    if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, n->u.id.number)->identifier_flags))    {    if(flags & WANT_LVALUE)    {    yyerror("Cannot assign functions.\n");    }else{ -  emit(F_LFUN,n->u.id.number); +  emit1(F_LFUN,n->u.id.number);    }    }else{    if(flags & WANT_LVALUE)    { -  emit(F_GLOBAL_LVALUE,n->u.id.number); +  emit1(F_GLOBAL_LVALUE,n->u.id.number);    return 2;    }else{ -  emit(F_GLOBAL,n->u.id.number); +  emit1(F_GLOBAL,n->u.id.number);    }    }    return 1;       case F_VAL_LVAL:    return do_docode(CAR(n),flags)+do_docode(CDR(n),flags | DO_LVALUE);       default:    fatal("Infernal compiler error (unknown parse-tree-token).\n");    return 0; /* make gcc happy */