pike.git/src/docode.c:37:
struct cleanup_frame *prev;
cleanup_func cleanup;
void *cleanup_arg;
int stack_depth;
};
struct statement_label_name
{
struct statement_label_name *next;
struct pike_string *str;
+ struct pike_string *file;
INT_TYPE line_number;
int used;
};
struct statement_label
{
struct statement_label *prev;
struct statement_label_name *name;
/* -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
pike.git/src/docode.c:265:
#endif
switch(x)
{
case 0: return;
case 1: emit0(F_POP_VALUE); break;
default: emit1(F_POP_N_ELEMS,x); break;
}
modify_stack_depth(-x);
}
+ static void do_pop_cleanup(void *x)
+ {
+ do_pop((int)(ptrdiff_t)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))
{
struct compilation *c = THIS_COMPILATION;
emit0(F_POP_TO_MARK);
pike.git/src/docode.c:300:
}
#define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP ))
int do_docode(node *n, int flags)
{
int i;
int stack_depth_save = current_stack_depth;
struct compilation *c = THIS_COMPILATION;
INT_TYPE save_current_line = c->lex.current_line;
+ struct pike_string *save_current_file = c->lex.current_file;
if(!n) return 0;
c->lex.current_line=n->line_number;
-
+ c->lex.current_file = n->current_file;
#ifdef PIKE_DEBUG
if (current_stack_depth == -4711) Pike_fatal("do_docode() used outside docode().\n");
#endif
i=do_docode2(n, flags);
current_stack_depth = stack_depth_save + i;
-
+ c->lex.current_file = save_current_file;
c->lex.current_line=save_current_line;
return i;
}
static int is_efun(node *n, c_fun fun)
{
return n && n->token == F_CONSTANT &&
SUBTYPEOF(n->u.sval) == FUNCTION_BUILTIN &&
n->u.sval.u.efun->function == fun;
}
pike.git/src/docode.c:615:
case F_AUTO_MAP_MARKER:
{
int depth=0;
while(n->token == F_AUTO_MAP_MARKER)
{
n=CAR(n);
depth++;
}
emit0(F_MARK);
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
code_expression(n, 0, "[*]");
emit1(F_NUMBER, depth);
emit_apply_builtin("__builtin.automap_marker");
-
+ POP_AND_DONT_CLEANUP;
return 1;
}
}
}
static void emit_builtin_svalue(char *func)
{
INT32 tmp1;
struct compilation *c = THIS_COMPILATION;
struct pike_string *n1=make_shared_string(func);
pike.git/src/docode.c:894: Inside #if defined(PIKE_DEBUG)
get_name_of_type(id->run_time_type),
id->run_time_type);
}
#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;
emit0(F_MARK);
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
code_expression(val, 0, "RHS");
emit_multi_assign(vals, vars, no+1);
emit1(F_CALL_LFUN, f);
-
+ POP_AND_DONT_CLEANUP;
emit0(F_POP_VALUE);
}
}
}
/* 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 */
pike.git/src/docode.c:995:
}
}
switch(n->token)
{
case F_MAGIC_INDEX:
case F_MAGIC_SET_INDEX:
case F_MAGIC_INDICES:
case F_MAGIC_VALUES:
case F_MAGIC_TYPES:
+ case F_MAGIC_ANNOTATIONS:
emit2(n->token,
n->u.node.b->u.sval.u.integer,
n->u.node.a->u.sval.u.integer);
return 1;
case F_EXTERNAL:
case F_GET_SET:
{
int level = 0;
struct program_state *state = Pike_compiler;
pike.git/src/docode.c:1424: Inside #if defined(PIKE_DEBUG)
id->identifier_flags,
get_name_of_type(id->run_time_type),
id->run_time_type);
}
#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;
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
if (flags & DO_POP) {
#ifndef USE_APPLY_N
emit0(F_MARK);
#endif
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
-
+ POP_AND_DONT_CLEANUP;
emit0(F_POP_VALUE);
return !(flags & DO_POP);
}
}
}
/* FALLTHRU */
case F_EXTERNAL:
/* Check that it is in this context */
if(Pike_compiler ->new_program->id == CAR(n)->u.integer.a)
{
pike.git/src/docode.c:1535:
emit2(F_REARRANGE,1,2);
ret++;
flags|=DO_POP;
}
#ifdef PIKE_DEBUG
if(tmp1 != 2)
Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
#endif
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
emit0(F_MARK);
-
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
emit0(F_MARK);
emit0(F_LTOSVAL);
emit1(F_NUMBER, depth);
emit_apply_builtin("__builtin.automap_marker");
-
+ POP_AND_DONT_CLEANUP;
emit_builtin_svalue("`+");
emit2(F_REARRANGE,1,1);
emit1(F_NUMBER, 1);
emit_apply_builtin("__automap__");
-
+ POP_AND_DONT_CLEANUP;
if(flags & DO_POP)
{
emit0(F_ASSIGN_AND_POP);
}else{
emit0(F_ASSIGN);
ret++;
}
return ret;
}else{
pike.git/src/docode.c:1597:
emit2(F_REARRANGE,1,2);
ret++;
flags|=DO_POP;
}
#ifdef PIKE_DEBUG
if(tmp1 != 2)
Pike_fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
#endif
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
emit0(F_MARK);
-
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
emit0(F_MARK);
emit0(F_LTOSVAL);
emit1(F_NUMBER, depth);
emit_apply_builtin("__builtin.automap_marker");
-
+ POP_AND_DONT_CLEANUP;
emit_builtin_svalue("`-");
emit2(F_REARRANGE,1,1);
emit1(F_NUMBER, 1);
emit_apply_builtin("__automap__");
-
+ POP_AND_DONT_CLEANUP;
if(flags & DO_POP)
{
emit0(F_ASSIGN_AND_POP);
}else{
emit0(F_ASSIGN);
ret++;
}
return ret;
}else{
pike.git/src/docode.c:1696:
if(CDDR(arr))
{
do_docode(CDDR(arr), DO_LVALUE);
}else{
emit0(F_CONST0);
emit0(F_CONST0);
modify_stack_depth(2);
}
- PUSH_CLEANUP_FRAME(do_pop, 5);
+ PUSH_CLEANUP_FRAME(do_pop_cleanup, 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
* current_label->break_label, but I'm playing safe. /mast */
tmp3 = alloc_label();
do_jump(F_FOREACH_START, (INT32) tmp3);
pike.git/src/docode.c:1760:
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);
modify_stack_depth(1);
foreach_arg_pushed:
- PUSH_CLEANUP_FRAME(do_pop, 4);
+ PUSH_CLEANUP_FRAME(do_pop_cleanup, 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);
DO_CODE_BLOCK(CDR(n));
ins_label(current_label->continue_label);
pike.git/src/docode.c:1791:
case F_INC_NEQ_LOOP:
case F_DEC_NEQ_LOOP:
case F_INC_LOOP:
case F_DEC_LOOP:
{
INT32 *prev_switch_jumptable = current_switch.jumptable;
BLOCK_BEGIN;
do_docode(CAR(n),0);
- PUSH_CLEANUP_FRAME(do_pop, 3);
+ PUSH_CLEANUP_FRAME(do_pop_cleanup, 3);
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);
DO_CODE_BLOCK(CDR(n));
ins_label(current_label->continue_label);
pike.git/src/docode.c:2383:
}
case F_NORMAL_STMT_LABEL:
case F_CUSTOM_STMT_LABEL: {
struct statement_label *label;
struct statement_label_name name;
BLOCK_BEGIN;
PUSH_STATEMENT_LABEL;
name.str = CAR(n)->u.sval.u.string;
name.line_number = n->line_number;
+ name.file = n->current_file;
name.used = 0;
for (label = current_label; label; label = label->prev) {
struct statement_label_name *lbl_name;
for (lbl_name = label->name; lbl_name; lbl_name = lbl_name->next)
if (lbl_name->str == name.str) {
INT_TYPE save_line = c->lex.current_line;
-
+ struct pike_string *save_file = c->lex.current_file;
c->lex.current_line = name.line_number;
-
+ c->lex.current_file = name.file;
my_yyerror("Duplicate nested labels, previous one on line %d.",
lbl_name->line_number);
c->lex.current_line = save_line;
-
+ c->lex.current_file = save_file;
goto label_check_done;
}
}
label_check_done:
name.next = current_label->name;
current_label->name = &name;
if (!name.next) {
if (n->token == F_CUSTOM_STMT_LABEL)
pike.git/src/docode.c:2761:
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);
+ PUSH_CLEANUP_FRAME(do_pop_mark, 0);
code_expression(CAR(n), 0, "automap function");
do_encode_automap_arg_list(CDR(n),0);
emit_apply_builtin("__automap__");
-
+ POP_AND_DONT_CLEANUP;
return 1;
case F_AUTO_MAP_MARKER:
if( flags & DO_LVALUE )
{
do_docode(CAR(n),DO_LVALUE);
}
else
{
yyerror("[*] not supported here.\n");
pike.git/src/docode.c:2791:
/* 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;
+ case F_SET_LOCAL_NAME:
+ tmp1 = store_prog_string(CDR(n)->u.sval.u.string);
+ emit2(F_SET_LOCAL_NAME, CAR(n)->u.sval.u.integer, tmp1);
+ return 0;
+
+ case F_SET_LOCAL_TYPE:
+ tmp1 = store_constant(&CDR(n)->u.sval, 0, NULL);
+ emit2(F_SET_LOCAL_TYPE, CAR(n)->u.sval.u.integer, tmp1);
+ return 0;
+
+ case F_SET_LOCAL_END:
+ emit1(F_SET_LOCAL_END, CAR(n)->u.sval.u.integer);
+ return 0;
+
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;