From 16d3e0133d9e5fd1052be69bfeec3b243d832ed4 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Wed, 9 Nov 2011 15:22:01 +0100 Subject: [PATCH] peval: don't copy assigned lexical bindings * module/language/tree-il/peval.scm (peval): Since constant-expression? is used to determine whether to copy values, return #f if any lexical is assigned. --- module/language/tree-il/peval.scm | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/module/language/tree-il/peval.scm b/module/language/tree-il/peval.scm index 0d6abb2f1..9524133bf 100644 --- a/module/language/tree-il/peval.scm +++ b/module/language/tree-il/peval.scm @@ -530,16 +530,18 @@ top-level bindings from ENV and return the resulting expression." (make-sequence src (append head (list tail))))))))))) (define (constant-expression? x) - ;; Return true if X is constant---i.e., if it is known to have no - ;; effects, does not allocate storage for a mutable object, and does - ;; not access mutable data (like `car' or toplevel references). + ;; Return true if X is constant, for the purposes of copying or + ;; elision---i.e., if it is known to have no effects, does not + ;; allocate storage for a mutable object, and does not access + ;; mutable data (like `car' or toplevel references). (let loop ((x x)) (match x (($ ) #t) (($ ) #t) (($ ) #t) - (($ _ req opt rest kw inits _ body alternate) - (and (every loop inits) (loop body) + (($ _ req opt rest kw inits syms body alternate) + (and (not (any assigned-lexical? syms)) + (every loop inits) (loop body) (or (not alternate) (loop alternate)))) (($ _ _ gensym) (not (assigned-lexical? gensym))) @@ -556,10 +558,12 @@ top-level bindings from ENV and return the resulting expression." (and (loop body) (every loop args))) (($ _ exps) (every loop exps)) - (($ _ _ _ vals body) - (and (every loop vals) (loop body))) - (($ _ _ _ _ vals body) - (and (every loop vals) (loop body))) + (($ _ _ syms vals body) + (and (not (any assigned-lexical? syms)) + (every loop vals) (loop body))) + (($ _ _ _ syms vals body) + (and (not (any assigned-lexical? syms)) + (every loop vals) (loop body))) (($ _ _ _ vals body) (and (every loop vals) (loop body))) (($ _ exp body) @@ -830,8 +834,10 @@ top-level bindings from ENV and return the resulting expression." (ops (make-bound-operands vars new vals visit)) (env* (fold extend-env env gensyms ops)) (body* (visit body counter ctx))) - (if (and (const? body*) - (every constant-expression? vals)) + (if (and (const? body*) (every constant-expression? vals)) + ;; We may have folded a loop completely, even though there + ;; might be cyclical references between the bound values. + ;; Handle this degenerate case specially. body* (prune-bindings ops in-order? body* counter ctx (lambda (names gensyms vals body) -- 2.20.1