From c7d6ddbf38d2019cf67882e6e5f3bd0cd5cfa155 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Sun, 24 May 2020 20:35:31 +0200 Subject: [PATCH] cmp: fix inlining of local closures (2nd try) We need to compile the function body in the same environment in which the function was defined. However the function arguments need to be compiled in the current argument. Fixes #577. --- src/cmp/cmpeval.lsp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/cmp/cmpeval.lsp b/src/cmp/cmpeval.lsp index ea5dcbb4f..5749c47aa 100644 --- a/src/cmp/cmpeval.lsp +++ b/src/cmp/cmpeval.lsp @@ -97,15 +97,31 @@ `(funcall ,can-inline ,@args))) (t (c1call-global fname args)))) +(defun inline-local (lambda fun args) + (declare (si::c-local)) + (let ((*inline-max-depth* (1- *inline-max-depth*)) + (setjmps *setjmps*) + (*cmp-env* (cmp-env-copy))) + ;; To inline the function, we transform it into a let* statement. + (multiple-value-bind (bindings body) + (transform-funcall/apply-into-let* (macroexpand-lambda-block lambda) + args nil) + (multiple-value-bind (let-vars let-inits specials other-decls body) + (process-let-bindings 'LET* bindings body) + ;; We have to compile the function body in the same + ;; environment in which the function was defined to get + ;; inlining of closures right. + (let ((*cmp-env* (cmp-env-copy (fun-cmp-env fun)))) + (mapc #'push-vars let-vars) + (process-let-body 'LET* let-vars let-inits specials other-decls body setjmps)))))) + (defun c1call-local (fname fun args) (declare (si::c-local)) (let ((lambda (fun-lambda-expression fun))) (when (and lambda (declared-inline-p fname) (plusp *inline-max-depth*)) - (return-from c1call-local - (let ((*inline-max-depth* (1- *inline-max-depth*))) - `(funcall #',lambda ,@args))))) + (return-from c1call-local (inline-local lambda fun args)))) (let* ((forms (c1args* args)) (return-type (or (get-local-return-type fun) 'T)) (arg-types (get-local-arg-types fun)))