pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:56:    /* -2 in break_label is used to flag "open" statement_label entries.    * If an open entry is on top of the stack, it's used instead of a    * new one. That's used to associate statement labels to the    * following statement. */    INT32 break_label, continue_label;    int emit_break_label;    int stack_depth;    struct cleanup_frame *cleanups;   };    - static struct statement_label top_statement_label_dummy = -  {0, 0, -1, -1, 0, -1, 0}; - static struct statement_label *current_label = &top_statement_label_dummy; + static struct statement_label *current_label = NULL; +    #ifdef PIKE_DEBUG   static int current_stack_depth = -4711;   #else   static int current_stack_depth = 0;   #endif      #define PUSH_CLEANUP_FRAME(func, arg) do { \    struct cleanup_frame cleanup_frame__; \    cleanup_frame__.cleanup = (cleanup_func) (func); \    cleanup_frame__.cleanup_arg = (void *)(ptrdiff_t) (arg); \    cleanup_frame__.stack_depth = current_stack_depth; \    DO_IF_DEBUG( \ -  +  if (!current_label) { \ +  Pike_fatal("no current_label!\n"); \ +  } \    if (current_label->cleanups == (void *)(ptrdiff_t) -1) \    Pike_fatal("current_label points to an unused statement_label.\n"); \    ) \    if (current_label->break_label == -2) { \    DO_IF_DEBUG( \    if (current_label->prev->break_label == -2) \    Pike_fatal("Found two open statement_label entries in a row.\n"); \    ) \    cleanup_frame__.prev = current_label->prev->cleanups; \    current_label->prev->cleanups = &cleanup_frame__; \
pike.git/src/docode.c:130:    if (d_flag > 2) emit0(F_POP_SYNCH_MARK); \    POP_AND_DONT_CLEANUP   #else   #define BLOCK_BEGIN   #define BLOCK_END   #endif      #define PUSH_STATEMENT_LABEL do { \    struct statement_label new_label__; \    new_label__.prev = current_label; \ -  if (current_label->break_label != -2) { \ +  if (!current_label || (current_label->break_label != -2)) { \    /* Only cover the current label if it's closed. */ \    new_label__.name = 0; \    new_label__.break_label = new_label__.continue_label = -1; \    new_label__.emit_break_label = 0; \    new_label__.cleanups = 0; \    new_label__.stack_depth = current_stack_depth; \    current_label = &new_label__; \    } \    else { \    DO_IF_DEBUG( \
pike.git/src/docode.c:1182:    return 1;    }    break;       case F_UNDEFINED:    yyerror("Undefined identifier");    emit1(F_NUMBER,0);    return 1;       case F_PUSH_ARRAY: { -  if (current_label != &top_statement_label_dummy || current_label->cleanups) { +  if (current_label) {    /* Might not have a surrounding apply node if evaluated as a    * constant by the optimizer. */   #ifdef PIKE_DEBUG    if (!current_label->cleanups ||    (current_label->cleanups->cleanup != do_pop_mark &&    current_label->cleanups->cleanup != do_pop_to_mark))    Pike_fatal("F_PUSH_ARRAY unexpected in this context.\n");   #endif    current_label->cleanups->cleanup = do_pop_to_mark;    }
pike.git/src/docode.c:3007:   }      /* 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;    INT32 generator_switch = -1, *generator_jumptable = NULL;    int aggregate_cnum = -1; -  int save_stack_depth = current_stack_depth; +     int save_label_no = label_no; -  +  struct statement_label *save_label;    int tmp1, tmp2; -  current_stack_depth = 0; +        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; -  +  PUSH_STATEMENT_LABEL; +  save_label = current_label->prev; +  current_label->prev = NULL; +  PUSH_CLEANUP_FRAME(NULL, NULL); +  current_stack_depth = 0;       /* NOTE: This is no ordinary label... */    low_insert_label(0);    emit0(F_ENTRY);    emit0(F_START_FUNCTION);       if (Pike_compiler->compiler_frame->generator_local != -1) {    INT32 e, states;       /* Save the arguments for later.
pike.git/src/docode.c:3236:    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);    -  current_stack_depth = save_stack_depth; +  current_stack_depth = cleanup_frame__.stack_depth; +  POP_AND_DONT_CLEANUP; +  current_label->prev = save_label; +  POP_STATEMENT_LABEL;    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;    int generator_local_save = Pike_compiler->compiler_frame->generator_local;    struct byte_buffer instrbuf_save = instrbuf; -  int stack_depth_save = current_stack_depth; -  struct statement_label *label_save = current_label; -  struct cleanup_frame *top_cleanups_save = top_statement_label_dummy.cleanups; +  struct statement_label *label_save;    -  +  PUSH_STATEMENT_LABEL; +  label_save = current_label->prev; +  current_label->prev = NULL; +  PUSH_CLEANUP_FRAME(NULL, NULL);    label_no=1;    current_stack_depth = 0; -  current_label = &top_statement_label_dummy; /* Fix these two to */ -  top_statement_label_dummy.cleanups = 0; /* please F_PUSH_ARRAY. */ +     Pike_compiler->compiler_frame->generator_local = -1;    init_bytecode();       insert_opcode0(F_ENTRY, n->line_number, n->current_file);    /* FIXME: Should we check that do_docode() returns 1? */    do_docode(n,0);    insert_opcode0(F_DUMB_RETURN, n->line_number, n->current_file);    entry_point = assemble(0); /* Don't store linenumbers. */       instrbuf=instrbuf_save;    Pike_compiler->compiler_frame->generator_local = generator_local_save; -  +  +  current_stack_depth = cleanup_frame__.stack_depth; +  POP_AND_DONT_CLEANUP; +  current_label->prev = label_save; +  POP_STATEMENT_LABEL; +  Pike_compiler->compiler_frame->generator_local = generator_local_save;    label_no = label_no_save; -  current_stack_depth = stack_depth_save; -  current_label = label_save; -  top_statement_label_dummy.cleanups = top_cleanups_save; +     return entry_point;   }