diff --git a/src/docode.c b/src/docode.c index dc9a96a38eb1ca47464323278cb9071c48085357..f67b59ed095ed05739f976d50a32ff43e2d2a590 100644 --- a/src/docode.c +++ b/src/docode.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: docode.c,v 1.194 2008/01/29 15:24:25 grubba Exp $ +|| $Id: docode.c,v 1.195 2008/01/29 20:08:39 grubba Exp $ */ #include "global.h" @@ -1210,29 +1210,37 @@ static int do_docode2(node *n, int flags) emit0(n->token); return n->token==F_ASSIGN; } -#if 0 - /* Not enabled, since it has side effects if the function throws. */ case F_APPLY: if ((CAAR(n)->token == F_CONSTANT) && (CAAR(n)->u.sval.type == T_FUNCTION) && - (CAAR(n)->u.sval.subtype == FUNCTION_BUILTIN)) { + (CAAR(n)->u.sval.subtype == 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) { - if (args->token == F_ARG_LIST) { - } else if (node_is_eq(CDR(n), args)) { + node **arg = my_get_arg(&args, 0); + if (arg && node_is_eq(CDR(n), *arg)) { + /* 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_LTOSVAL1); + 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_CALL_BUILTIN1, DO_NOT_WARN((INT32)tmp1)); - emit0(n->token); + emit1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, DO_NOT_WARN((INT32)tmp1)); + POP_AND_DONT_CLEANUP; return 1; } } } -#endif /* 0 */ default: switch(CDR(n)->token)