summaryrefslogtreecommitdiff
path: root/Lisp/internal-utilities.lisp
diff options
context:
space:
mode:
authorMatthias Benkard <code@mail.matthias.benkard.de>2007-09-17 22:57:13 +0200
committerMatthias Benkard <code@mail.matthias.benkard.de>2007-09-17 22:57:13 +0200
commita49631ce9185a362f48bb31578287fbe705f9ee6 (patch)
treeaab810ede90d36073713679347a2bbf52fc43dc6 /Lisp/internal-utilities.lisp
parent0ec83cb4b02d2d7f827e4aa5bd9f32a01e5011de (diff)
Cache the return values of RETRIEVE-METHOD-SIGNATURE-INFO.
darcs-hash:17a199077cab37197bbcbc48d58100c4dd73e76e
Diffstat (limited to 'Lisp/internal-utilities.lisp')
-rw-r--r--Lisp/internal-utilities.lisp26
1 files changed, 26 insertions, 0 deletions
diff --git a/Lisp/internal-utilities.lisp b/Lisp/internal-utilities.lisp
index 818c18b..4e9d481 100644
--- a/Lisp/internal-utilities.lisp
+++ b/Lisp/internal-utilities.lisp
@@ -75,3 +75,29 @@
(if (find-symbol "FOREIGN-FUNCALL-POINTER" '#:cffi)
`(cffi:foreign-funcall-pointer ,pointer ,options ,@args)
`(cffi:foreign-funcall (,pointer ,@options) ,@args))))
+
+
+;; Caching of function values.
+(defmacro define-cached-function (name lambda-list hashing-form &body body)
+ "Define a function and cache its result in a hash table. The hash key
+is computed according to HASHING-FORM.
+
+Note that HASHING-FORM is expected to return a freshly consed object
+that can be garbage collected. It is not recommended to use an atom as
+a HASHING-FORM if the value of the atom might itself be an interned atom
+or any other value that might never be deleted by the garbage
+collector."
+ (let ((hash-table (gensym))
+ (value (gensym))
+ (default-value (gensym))
+ (hash-key (gensym)))
+ `(let ((,hash-table (tg:make-weak-hash-table :weakness :key
+ :test 'equal)))
+ (defun ,name ,lambda-list
+ (let* ((,hash-key ,hashing-form)
+ (,value (gethash ,hash-key ,hash-table ',default-value)))
+ (if (eq ',default-value ,value)
+ (values-list
+ (setf (gethash ,hash-key ,hash-table)
+ (multiple-value-list (progn ,@body))))
+ (values-list ,value)))))))