pike.git
/
src
/
docode.c
version
»
Context lines:
10
20
40
80
file
none
3
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;