X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ffdefinition.lisp;h=7b627effb057893261c3b0ba7152743b9d0d3b72;hb=bee53328c93be3433477821131ab805557476c8b;hp=0b72f217b54455d1cbcbc9e209e6ea7040095a70;hpb=cea4896b2482b7b2b429c1631d774b4cfbc0efba;p=sbcl.git diff --git a/src/code/fdefinition.lisp b/src/code/fdefinition.lisp index 0b72f21..7b627ef 100644 --- a/src/code/fdefinition.lisp +++ b/src/code/fdefinition.lisp @@ -55,13 +55,7 @@ "Return the fdefn object for NAME. If it doesn't already exist and CREATE is non-NIL, create a new (unbound) one." (declare (values (or fdefn null))) - (unless (or (symbolp name) - (and (consp name) - (eq (car name) 'setf) - (let ((cdr (cdr name))) - (and (consp cdr) - (symbolp (car cdr)) - (null (cdr cdr)))))) + (unless (legal-function-name-p name) (error 'simple-type-error :datum name :expected-type '(or symbol list) @@ -175,7 +169,8 @@ ;;;; definition encapsulation (defstruct (encapsulation-info (:constructor make-encapsulation-info - (type definition))) + (type definition)) + (:copier nil)) ;; This is definition's encapsulation type. The encapsulated ;; definition is in the previous encapsulation-info element or ;; installed as the global definition of some function name. @@ -185,34 +180,42 @@ ;; replaced by an encapsulation of type TYPE. (definition nil :type function)) -;;; We must bind and close over info. Consider the case where we -;;; encapsulate (the second) an encapsulated (the first) definition, -;;; and later someone unencapsulates the encapsulated (first) -;;; definition. We don't want our encapsulation (second) to bind -;;; basic-definition to the encapsulated (first) definition when it no -;;; longer exists. When unencapsulating, we make sure to clobber the -;;; appropriate info structure to allow basic-definition to be bound -;;; to the next definition instead of an encapsulation that no longer -;;; exists. +;;; Replace the definition of NAME with a function that binds NAME's +;;; arguments a variable named argument-list, binds name's definition +;;; to a variable named basic-definition, and evaluates BODY in that +;;; context. TYPE is whatever you would like to associate with this +;;; encapsulation for identification in case you need multiple +;;; encapsulations of the same name. (defun encapsulate (name type body) - #!+sb-doc - "Replaces the definition of NAME with a function that binds name's arguments - a variable named argument-list, binds name's definition to a variable named - basic-definition, and evaluates BODY in that context. TYPE is - whatever you would like to associate with this encapsulation for - identification in case you need multiple encapsuations of the same name." (let ((fdefn (fdefinition-object name nil))) (unless (and fdefn (fdefn-function fdefn)) (error 'undefined-function :name name)) + ;; We must bind and close over INFO. Consider the case where we + ;; encapsulate (the second) an encapsulated (the first) + ;; definition, and later someone unencapsulates the encapsulated + ;; (first) definition. We don't want our encapsulation (second) to + ;; bind basic-definition to the encapsulated (first) definition + ;; when it no longer exists. When unencapsulating, we make sure to + ;; clobber the appropriate INFO structure to allow + ;; basic-definition to be bound to the next definition instead of + ;; an encapsulation that no longer exists. (let ((info (make-encapsulation-info type (fdefn-function fdefn)))) (setf (fdefn-function fdefn) - #'(lambda (&rest argument-list) - (declare (special argument-list)) - (let ((basic-definition (encapsulation-info-definition info))) - (declare (special basic-definition)) - (eval body))))))) + (lambda (&rest argument-list) + (declare (special argument-list)) + (let ((basic-definition (encapsulation-info-definition info))) + (declare (special basic-definition)) + (eval body))))))) + +;;; This is like FIND-IF, except that we do it on a compiled closure's +;;; environment. +(defun find-if-in-closure (test fun) + (dotimes (index (1- (get-closure-length fun))) + (let ((elt (%closure-index-ref fun index))) + (when (funcall test elt) + (return elt))))) -;;; Finds the encapsulation info that has been closed over. +;;; Find the encapsulation info that has been closed over. (defun encapsulation-info (fun) (and (functionp fun) (= (get-type fun) sb!vm:closure-header-type) @@ -346,7 +349,7 @@ (defun fmakunbound (name) #!+sb-doc - "Make Name have no global function definition." + "Make NAME have no global function definition." (let ((fdefn (fdefinition-object name nil))) (when fdefn (fdefn-makunbound fdefn)))