1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
10 (in-package "SB-INTERPRETER")
12 ;;;; This interpreter is a hybrid of a traditional recursive descent EVAL,
13 ;;;; augmented with some semantic preprocessing. But unlike most other
14 ;;;; preprocessing implementations which produce code which emulates compiled
15 ;;;; code as closely as possible by performing macroexpansion once only,
16 ;;;; we attempt to emulate a non-preprocessing interpreter.
17 ;;;; The motivation for this is parenthetically revealed in the X3J13 issue
18 ;;;; discussing the removal of COMPILER-LET, saying:
19 ;;;; "Some users have indicated they dislike interpreters which do a semantic
20 ;;;; prepass, because they like to be able to dynamically redefine macros
21 ;;;; while debugging."
22 ;;;; In addition, preprocessing of a form is done as late as possible -
23 ;;;; only when a form is reached - and only enough to descend one level.
25 ;;; SEXPRs are the basic building blocks of interpreted code.
26 ;;; We store a function to call (in the HANDLER) as well as the original
27 ;;; list representation of the form in case it has to be re-preprocessed.
28 (defstruct (sexpr (:conc-name sexpr-
)
29 (:constructor %make-sexpr
(handler %form
))
31 (handler nil
:type cons
)
32 (%form nil
:read-only t
)) ; the original source form
34 ;;; A SEXPR's HANDLER is a cons. This constructs a HANDLER.
35 (defun %handler
(function payload
) (cons function payload
))
37 ;;; Not all "sexprs" are actually instances of SEXPR,
38 ;;; because self-evaluating constants are stored as-is.
39 ;;; Get the original source out of a SEXPR-equivalent object.
40 (defun sexpr-form (object)
41 (if (%instancep object
)
42 (progn (aver (sexpr-p object
)) (sexpr-%form object
))
45 ;;; Wrapper to hide the argument passing convention.
46 ;;; This is preferable to using a closure over the handler-function and args
47 ;;; because it makes for better inspectability and is often more compact.
48 ;;; The smallest closure requires 4 words; this has a lower bound of 2 words.
50 ;;; FIXME: the preceding claim about inspectability is no longer true now that
51 ;;; we have STORE-CLOSURE-DEBUG-POINTER which can preserve both the lexical
52 ;;; and dynamic state. And the efficiency claim might never have been true.
53 (defmacro handler
(function &rest args
)
55 `(%handler
,function
0))
57 `(%handler
,function
,(first args
)))
59 `(%handler
,function
(cons ,(first args
) ,(second args
))))
61 `(%handler
,function
(vector ,@args
)))))
63 (defmacro with-form-data
(names input
&body body
)
64 (declare (list names
))
67 (1 `((,(first names
) ,input
)))
68 (2 `((,(car names
) (car ,input
)) (,(cadr names
) (cdr ,input
))))
69 (t (loop for name in names for i from
0
70 collect
`(,name
(svref ,input
,i
)))))
73 ;;; Wrapper on LAMBDA for writing handlers.
74 ;;; (HLAMBDA NAME (DATA ENV SEXPR) ...)
75 ;;; -> (NAMED-LAMBDA (EVAL NAME) (#:DATA ENV SEXPR)
76 ;;; (WITH-FORM-DATA DATA #:DATA ...)
78 ;;; If DATA is a symbol, it is used literally as the first formal parameter
79 ;;; in the lambda; if it is a list, the lambda receives one thing which is
80 ;;; destructured according to the argument passing convention.
82 ;;; If SEXPR is omitted it becomes a gensym which gets declared ignore.
83 ;;; All handlers have identical signature but most don't use the third argument.
84 ;;; Only a handler which can restart by discarding internal state needs it.
86 (defmacro hlambda
(name captured-vars vars
&body body
)
87 (declare (list captured-vars
))
88 (let ((data (gensym "DATA")) (ignore))
89 ;; Allow &AUX vars: (HLAMBDA NAME (DATA ENV &AUX FOO) ...) has no 3rd arg.
90 (let ((aux-vars (member '&aux vars
)))
91 (when (= (length (ldiff vars aux-vars
)) 1)
92 (let ((sexpr (make-symbol "SEXPR")))
93 (setq vars
(nconc (subseq vars
0 1) (list sexpr
) aux-vars
)
94 ignore
`((ignore ,sexpr
))))))
95 (setq name
(cons '.eval.
(if (listp name
) name
(list name
))))
96 `(handler ,(if captured-vars
97 (if (= (length captured-vars
) 1)
98 `(named-lambda ,name
(,(first captured-vars
) ,@vars
)
99 (declare ,+handler-optimize
+ ,@ignore
)
101 `(named-lambda ,name
(,data
,@vars
)
102 (declare ,+handler-optimize
+ ,@ignore
)
103 (with-form-data ,captured-vars
,data
,@body
)))
104 `(named-lambda ,name
(,data
,@vars
)
105 (declare ,+handler-optimize
+ (ignore ,data
) ,@ignore
)
109 ;;; DISPATCH receives a SEXPR object or sexpr-equivalent object.
110 ;;; If a SEXPR, its handler is called to produce a value. All other Lisp
111 ;;; objects are treated as constants.
112 ;;; N.B.: herein SEXPR sometimes mean either a SEXPR object, or a constant
113 ;;; object that needs no wrapping. The union of those could be envisioned
114 ;;; as a deftype DISPATCHABLE - which is nowise helpful in practice.
116 ;;; It is always ok to call DISPATCH on a SEXPR-equivalent object, but in two
117 ;;; places %DISPATCH is used to avoid a spurious code-deletion note where
118 ;;; SEXPR is known to be a dispatchable instance. This is one of the
119 ;;; "spurious but not wrong" notes that the compiler can emit.
120 (declaim (inline dispatch %dispatch
))
121 (defun %dispatch
(sexpr env
)
122 (declare #.
+handler-optimize
+)
123 (let ((handler (sexpr-handler sexpr
)))
124 (funcall (the function
(car handler
)) (cdr handler
) env sexpr
)))
125 (defun dispatch (sexpr env
)
126 (declare #.
+handler-optimize
+)
127 (if (%instancep sexpr
) (%dispatch sexpr env
) sexpr
))
129 ;;; Helper for RETURN-CONSTANT.
130 ;;; Would be a local function except for some uses of LOAD-TIME-VALUE.
131 (defun %const
(x env sexpr
)
132 (declare (ignore env sexpr
) #.
+handler-optimize
+)
135 ;;; Return a handler that returns a constant.
136 ;;; The %SEXPR constructor elides a handler for constants,
137 ;;; but there are cases where NIL sneaks through and demands a callable handler.
138 ;;; We avoid generating N copies of such handler. Same goes for 0 and T.
139 (defun return-constant (object)
140 (cond ((null object
) (load-time-value (handler #'%const nil
)))
141 ((eq object t
) (load-time-value (handler #'%const t
)))
142 ((eql object
0) (load-time-value (handler #'%const
0)))
143 (t (handler #'%const object
))))
145 (defun return-constant-values (values env sexpr
)
146 (declare (ignore env sexpr
) #.
+handler-optimize
+)
147 (values-list values
))
150 (declaim (ftype function digest-form %eval eval-setq
))
152 ;;; Return a SEXPR object that will, when dispatched, evaluate FORM.
153 ;;; Unlike optimizations on SEXPRS whereby they install the most-specific
154 ;;; applicable handler for a given source form when first dispatched, constants
155 ;;; can't do that because by the time DIGEST-FORM is dispatched, it's too late
156 ;;; to install a function other than #'RETURN-CONSTANT. The goal here is to
157 ;;; avoid funcalling anything on constant forms. Therefore:
158 ;;; 1. For most self-evaluating objects, FORM itself is returned.
159 ;;; Structures are self-evaluating, but have to be wrapped because DISPATCH
160 ;;; assumes that anything satisfying %INSTANCEP is a dispatchable object.
161 ;;; 2. If FORM is a syntactically correct QUOTE form, return the quoted thing
162 ;;; subject to the constraint in condition 1. SEXPRs are prepared in advance
163 ;;; of being EVALed, so no errors may be signaled on malformed QUOTE forms.
165 ;;; Todo: there is still more opportunity for lifting singleton PROGN forms.
166 ;;; Lots of standard macros expand into (PROGN (ONE-THING)), which, if it appears
167 ;;; as the argument to %SEXPR should just become a SEXPR for (ONE-THING).
171 (cond ((and (atom form
)
172 (not (%instancep form
))
173 (or (not (symbolp form
))
174 ;; Only builtin constants and keywords are assumed
175 ;; to be written in stone. Others generate a continuable
176 ;; error on redefinition, and this eval will always
177 ;; get the current definition.
178 (and (eq (info :variable
:kind form
) :constant
)
179 (memq (symbol-package form
)
180 (load-time-value (list (find-package "KEYWORD")
181 (find-package "CL"))))
182 (progn (setq form
(symbol-value form
)) t
))))
185 (eq (car form
) 'quote
)
186 (consp (setq cdr
(cdr form
)))
188 (not (%instancep
(setq obj
(car cdr
)))))
190 (t ; DIGEST-FORM is the generic handler
191 (%make-sexpr
(handler #'digest-form form
) form
)))))
193 ;;; Return a SEXPR that will evaluate zero or more FORMS.
194 (defun %progn
(forms)
195 ;; The handler for PROGN contains code to handle 0, 1, 2, 3+ subforms
196 ;; but it's worthwhile to special-case 0 and 1 here too
197 ;; because it avoids some consing and preprocessing.
198 (%sexpr
(if (and (listp forms
) (not (cdr forms
)))
199 (first forms
) ; ok if (PROGN) or (PROGN form)
202 ;;; Return the binding of a lexical function indexed by INDEX in ENV.
203 ;;; INDEX must be the frame-ptr returned from a call to FIND-LEXICAL-FUN.
204 ;;; This is for runtime use by a SEXPR handler.
205 ;;; The name is borrowed from the standard function "FDEFINITION" -
206 ;;; this does not have anything to do with #<fdefn> objects.
207 (defun local-fdefinition (index env
)
208 (declare (fixnum index
) #.
+handler-optimize
+)
209 (%cell-ref env index
))
211 ;;; Return a frame-pointer for FNAME if it is a local function,
212 ;;; or return :MACRO if it names either a local *or* global macro.
213 ;;; Return NIL if none of the above.
214 (defun local-fn-frame-ptr (fname env
)
215 (multiple-value-bind (kind definition frame-ptr
) (find-lexical-fun env fname
)
217 (if (eq kind
:macro
) :macro frame-ptr
)
218 (if (and (symbolp fname
) (macro-function fname
)) :macro nil
))))
220 ;;; Fast handlers for lexical var access. This is a speed and space win,
221 ;;; the latter since it avoids some consing for small fixed frame-ptr.
223 ;;; (REF 0 N) -> (SVREF (ENV-VARS ENV) N)
224 ;;; (REF 1 N) -> (SVREF (ENV-VARS (ENV-PARENT ENV)) N)
225 ;;; (REF 2 N) -> (SVREF (ENV-VARS (ENV-PARENT (ENV-PARENT ENV))) N)
227 ;;; A fast assembler could generate accessors on demand - and then I'd cache
228 ;;; them - as the code is entirely boilerplate. Lacking that, hardwire some.
229 (declaim ((simple-array t
(4 10)) *fast-lexvar-reffers
* *fast-lexvar-setters
*))
230 (macrolet ((ref (up across
)
231 (declare (optimize (speed 0))) ; silence the generic math note
232 `(svref (env-payload ,(let ((e 'env
))
234 (setq e
`(env-parent ,e
)))))
236 (array-of (n-depths n-cells
)
237 (declare (optimize (speed 0))) ; silence the generic math note
239 ',(list n-depths n-cells
)
241 (list ,@(loop for depth below n-depths
243 `(list ,@(loop for j below n-cells
244 collect
`(access ,depth
,j
))))))))
245 (defparameter *fast-lexvar-reffers
*
246 (macrolet ((access (up across
)
247 `(hlambda GET-VAR
() (env) (ref ,up
,across
))))
248 (array-of 4 10))) ; for 4 scopes and 10 names per scope you can go fast
249 (defparameter *fast-lexvar-setters
* ; These are lambdas, not handlers
250 (macrolet ((access (up across
)
251 `(named-lambda (eval SET-VAR
) (form env sexpr
)
252 (declare #.
+handler-optimize
+ (ignore sexpr
))
253 (setf (ref ,up
,across
) (dispatch form env
)))))
256 (declaim (ftype (function (symbol t t
) nil
) typecheck-fail typecheck-fail
/ref
)
257 (ftype (function (t &rest t
) nil
) values-typecheck-fail
)
258 (ftype (function (function fixnum
) nil
)
259 err-too-few-args err-too-many-args
))
261 (macrolet ((with-indices (special-case general-case
)
262 `(let ((depth (frame-ptr-depth frame-ptr
))
263 (slot (frame-ptr-cell-index frame-ptr
)))
264 (if (and (< depth
(array-dimension *fast-lexvar-reffers
* 0))
265 (< slot
(array-dimension *fast-lexvar-reffers
* 1)))
269 ;; Return a handler that accesses a lexical var given its FRAME-PTR.
270 ;; Anything not in *FAST-LEXVAR-REFFERS* gets a general-purpose routine.
271 (defun lexvar-reffer (frame-ptr type
)
273 ;; There are no specialized reffers with type-checking
274 ;; because the check is slow anyway.
275 (hlambda GET-VAR
(frame-ptr type
) (env)
276 (let ((val (%cell-ref env frame-ptr
)))
277 (if (itypep val type
)
279 (typecheck-fail/ref
(frame-symbol env frame-ptr
) val type
))))
280 (with-indices (aref *fast-lexvar-reffers
* depth slot
)
281 (hlambda GET-VAR
(frame-ptr) (env) (%cell-ref env frame-ptr
)))))
283 (defun lexvar-setter (frame-ptr newval type
)
285 ;; There are no no specialized setters with type-checking
286 ;; because the check is slow anyway.
287 (hlambda SET-VAR
(newval frame-ptr type
) (env)
288 (let ((newval (dispatch newval env
)))
289 (if (itypep newval type
)
290 (setf (%cell-ref env frame-ptr
) newval
)
291 (typecheck-fail (frame-symbol env frame-ptr
) newval type
))))
292 (with-indices (handler (aref *fast-lexvar-setters
* depth slot
) newval
)
293 (hlambda SET-VAR
(newval frame-ptr
) (env)
294 (setf (%cell-ref env frame-ptr
) (dispatch newval env
)))))))
296 ;;; Access SYMBOL's dynamic value, enforcing TYPE if non-nil,
297 ;;; and checking for change of its :VARIABLE :KIND if PARANOID,
298 ;;; allowing the possibility that a DEFVAR changed to DEFINE-SYMBOL-MACRO
300 (defun specvar-reffer (symbol type
&optional paranoid
)
301 (macrolet ((safe-symbol-value ()
302 ;; HLAMBDA lowers safety because the interpreter itself
303 ;; is (hopefully) free of bugs, but we always want to check
304 ;; that a special variable is BOUNDP.
305 '(locally (declare (optimize (safety 3)))
306 (symbol-value symbol
))))
307 (cond ((and type paranoid
)
308 (hlambda SYMEVAL
(symbol) (env sexpr
)
309 (if (member (info :variable
:kind symbol
) '(:alien
:macro
))
310 (digest-form symbol env sexpr
)
311 (let ((val (safe-symbol-value)))
312 (if (itypep val type
)
314 (typecheck-fail/ref symbol val type
))))))
315 ((and type
(not paranoid
))
316 (hlambda SYMEVAL
(symbol type
) (env)
318 (let ((val (safe-symbol-value)))
319 (if (itypep val type
)
321 (typecheck-fail/ref symbol val type
)))))
323 (hlambda SYMEVAL
(symbol type
) (env sexpr
)
324 (if (member (info :variable
:kind symbol
) '(:alien
:macro
))
325 (digest-form symbol env sexpr
)
326 (safe-symbol-value))))
328 (hlambda SYMEVAL
(symbol) (env)
330 (safe-symbol-value))))))
332 (defconstant +mode-mask-shift
+ 4)
333 (defconstant +arg-mode-mask
+ #b1110
)
334 (defconstant +optional-arg
+ #b0000
)
335 (defconstant +keyword-arg
+ #b0010
)
336 (defconstant +supplied-p-var
+ #b0100
)
337 (defconstant +aux-var
+ #b0110
)
338 (defconstant +rest-arg
+ #b1000
)
339 ;;; This constant MUST be 1 so it can be used as an index skip count
340 ;;; versus having to write (if (logtest foo +has-default+) (incf thing))
341 (defconstant +has-default
+ #b0001
)
343 (defmacro argument-keyword-index
(encoding)
344 `(ash ,encoding
(- +mode-mask-shift
+)))
346 ;;; Compress LAMBDA-LIST into a representation that encodes which arguments
347 ;;; have defaulting forms and/or supplied-p variables.
348 (defun encode-lambda-bindings (lambda-list form-converter
)
349 (let ((n-optional 0) (n-keys -
1) fancy-vars decoder keys
)
350 (multiple-value-bind (llks required optional rest keyword-args aux
)
351 (parse-lambda-list lambda-list
352 :accept
(lambda-list-keyword-mask
353 '(&optional
&rest
&key
&allow-other-keys
&aux
))
355 ;; Do I need more syntax checking? PARSE-LAMBDA-LIST enforces syntactic
356 ;; validity but not that the vars are bindable; however the specialness
357 ;; check enforces the latter, so we're probably ok.
358 (flet ((add-var (x mode
)
359 (multiple-value-bind (key var
)
360 (if (eq mode
+keyword-arg
+)
361 (cond ((atom x
) (values (keywordicate x
) x
))
362 ((consp (car x
)) (values (caar x
) (cadar x
)))
363 (t (values (keywordicate (car x
))
365 (values nil
(if (symbolp x
) x
(car x
))))
366 (let* ((default (if (listp x
) (funcall form-converter x
)))
367 (encoding (logior mode
(if default
+has-default
+ 0))))
368 (push var fancy-vars
)
369 (when (eq mode
+keyword-arg
+)
370 (setq encoding
(logior (ash (incf n-keys
) +mode-mask-shift
+)
373 (push encoding decoder
)
375 (push default decoder
)))
376 (when (and (/= mode
+aux-var
+) (proper-list-of-length-p x
3))
377 (push (third x
) fancy-vars
)
378 (push +supplied-p-var
+ decoder
)))))
381 (add-var x
+optional-arg
+))
383 (push (car rest
) fancy-vars
)
384 (push +rest-arg
+ decoder
))
385 (dolist (x keyword-args
)
386 (add-var x
+keyword-arg
+))
388 (add-var x
+aux-var
+)))
389 (values required
(nreverse fancy-vars
)
390 ;; compute (length keys) before nreconc smashes them
391 (make-keyword-bits (length keys
) rest
392 (ll-kwds-keyp llks
) (ll-kwds-allowp llks
))
393 (if (or (ll-kwds-keyp llks
) decoder
)
394 (coerce (nreconc keys
(nreverse decoder
)) 'vector
))
397 ;;; If BODY matches (BLOCK <name> . <forms>) then return the block name, the
398 ;;; forms, and an indicator of whether it is OK to create the block and bind
399 ;;; variables at the same time. If not a block, return 0 and forms unaltered.
401 ;;; The optimization of eliding an extra ENV is performed only if no nontrival
402 ;;; defaulting SEXPRs exist. A "trivial" one is either a constant or a reference
403 ;;; to a variable (not a macro). Absent such a thing, nobody could notice that
404 ;;; there aren't actually two different lexical contours, so creating variable
405 ;;; bindings and a block may occur simultaneously.
406 ;;; [In fact, in such case, there is no difference between parallel and serial
407 ;;; binding, so the LET* part of the binding loop could be absorbed by the LET
408 ;;; part, which would have to be informed how to decode a fancy-arg vector]
409 ;;; The test is extremely paranoid by "wrongly" saying that a form can be a
410 ;;; macro despite the lambda list itself creating a binding for the symbol
411 ;;; in question. LAMBDA can cause fewer symbols to be macros, but never more.
412 ;;; Therefore it is fine to disregard the lambda decoder. For example in:
413 ;;; (symbol-macrolet ((foo (hair))) (lambda (x &optional (foo x)) ...)
414 ;;; FOO is thought to be a macro.
416 (defun extract-lambda-block (body decoder env
)
417 (labels ((definitely-var-ref-p (x)
419 (case (nth-value 1 (find-lexical-var env x
))
420 ((:normal
:special
) t
)
422 (t (neq (info :variable
:kind x
) :macro
)))))
423 (trivial-expression-p (x)
424 (or (not (sexpr-p x
)) ; a constant
425 (definitely-var-ref-p (sexpr-form x
)))))
426 (if (and (listp body
)
428 (eq (caar body
) 'block
)
430 (symbolp (cadar body
)))
431 (let ((body (cdar body
))) ; = (BLOCK-NAME . FORMS)
432 (values (car body
) (cdr body
)
433 (every #'trivial-expression-p decoder
)))
434 (values 0 body nil
))))
436 ;;; Produce a LAMBDA-FRAME for a PROTO-FN.
437 ;;; ENV is for package-lock checks and also to make a quick guess about
438 ;;; whether a block can be created at the same time as the variable bindings.
439 (defun digest-lambda (env proto-fn
)
441 (((required-args other-args keyword-bits decoder n-opt
)
442 (encode-lambda-bindings (proto-fn-lambda-list proto-fn
)
443 (lambda (x) (%sexpr
(second x
)))))
444 (decls (proto-fn-decls proto-fn
))
445 (n-required (length required-args
))
446 (n-other (length other-args
))
447 (n-lambda-vars (+ n-required n-other
))
448 (declared-specials (declared-specials decls
))
450 (remove-if (lambda (sym)
451 (or (memq sym required-args
) (memq sym other-args
)))
454 (let ((a (make-array (+ n-lambda-vars
(length free-specials
)))))
455 (replace a required-args
)
456 (replace a other-args
:start1 n-required
)
457 (replace a free-specials
:start1 n-lambda-vars
)
458 (dotimes (i n-lambda-vars a
) ; Unique-ify the binding cells.
459 (setf (svref a i
) (list (svref a i
))))))
461 (mark-bound-specials env declared-specials symbols n-lambda-vars
))
462 (required-mask (lognot (ash -
1 n-required
)))
463 (required-specials ; one list for PROGV in WITH-LET-BINDINGS
464 (nreverse ; WITH-LET-BINDINGS uses PUSH to accumulate values
465 (collect-progv-symbols
466 symbols n-lambda-vars
(logand special-b required-mask
))))
467 (other-specials ; one list per PROGV in WITH-LET*-BINDINGS.
469 (collect-progv-symbols
470 symbols n-lambda-vars
(logandc2 special-b required-mask
))))
471 ((block-name forms block-share-env-p
)
472 (extract-lambda-block (proto-fn-forms proto-fn
) decoder env
))
473 (frame (make-lambda-frame
474 :min-args n-required
:n-optional n-opt
475 :n-bound-vars n-lambda-vars
:keyword-bits keyword-bits
476 :symbols symbols
:values
(or decoder
#())
478 :specials
(if required-specials
479 (cons required-specials other-specials
)
481 :declarations decls
:%policy
(new-policy env decls
)
482 :block-name block-name
:share-block-p block-share-env-p
483 :sexpr
(%progn forms
))))
484 (process-typedecls frame env n-lambda-vars symbols
)
485 (setf (proto-fn-%frame proto-fn
) frame
486 (proto-fn-cookie proto-fn
) *globaldb-cookie
*)
487 (values frame
*globaldb-cookie
*)))
489 (defun make-local-fn-scope (decls funs forms env
)
490 (let ((specials (free-specials env decls
)))
491 (process-typedecls (%make-local-fn-scope
492 decls
(new-policy env decls
)
493 funs
(%progn forms
) specials
)
496 (defun err-too-few-args (fun n-args
)
497 (declare (explicit-check))
498 (let ((frame (interpreted-function-frame fun
)))
499 (ip-error "~S received ~D argument~:P but expects~:[ at least~;~] ~D."
500 (name-for-fun fun
) n-args
501 (eql (lambda-frame-min-args frame
) (lambda-frame-max-args frame
))
502 (lambda-frame-min-args frame
))))
504 (defun err-too-many-args (fun n-args
)
505 (declare (explicit-check))
506 (let ((frame (interpreted-function-frame fun
)))
507 (ip-error "~S received ~D argument~:P but expects~:[ at most~;~] ~D"
508 (name-for-fun fun
) n-args
509 (eql (lambda-frame-min-args frame
) (lambda-frame-max-args frame
))
510 (lambda-frame-max-args frame
))))
512 (defmacro with-lambda-frame
((frame-var fun if-invalid
) &body if-valid
)
513 ;; If any global variable has changed its :KIND, this function's lambda
514 ;; variables will be re-checked for specialness, constness, etc.;
515 ;; also, internally cached cached macroexpansions get discarded.
516 `(if (eq (interpreted-function-cookie ,fun
) *globaldb-cookie
*)
517 (let ((,frame-var
(interpreted-function-frame ,fun
)))
519 (progn (atomic-incf *invalidation-count
*) ; for testing cache eviction
522 ;;; LIST is a list of supplied keywords arguments to a function.
523 ;;; CONTROL-BITS are from the lambda frame, and ALLOWED is a vector
524 ;;; of the permitted keywords but has extra stuff after them, so scanning
525 ;;; must restrict itself to strictly the N-KEYS specified by CONTROL-BITS.
526 (defun validate-keywords (list control-bits allowed
)
527 (declare (list list
) (fixnum control-bits
) (simple-vector allowed
))
528 (labels ((check-odd-length (tail n-seen
)
529 (let ((n-more (length tail
))) ; just check for oddness
531 (fail-odd-length (+ n-seen n-more
)))))
533 (ip-error "odd number of &KEY arguments: ~D" n
))
535 (let ((n-allowed (keyword-bits-n-keys control-bits
)) bad
)
536 (loop for
(key val
) on list by
#'cddr
; rescan to collect them
537 unless
(or (eq key
:allow-other-keys
)
538 (find key allowed
:end n-allowed
))
539 do
(pushnew key bad
))
540 (let ((plural (cdr bad
)))
541 (ip-error "Keyword~*~:[~;s~]~2:* ~{~S~^,~} ~:[is~;are~] not ~
542 ~:[allowed.~;in the allowed set ~:*~S~]"
543 (nreverse bad
) plural
544 (replace (make-list n-allowed
) allowed
))))))
545 (if (keyword-bits-allowp control-bits
)
546 (check-odd-length list
0)
547 (let ((n-allowed (keyword-bits-n-keys control-bits
))
548 (allow-other +none
+) ; the observed value of :ALLOW-OTHER-KEYS
551 (seen-unknown-key-p nil
))
554 (if seen-unknown-key-p
557 (let ((key (pop tail
))
558 (value (if tail
(pop tail
) (fail-odd-length (1+ n-visited
)))))
560 ;; The code below is designed to pass or fail as soon as possible
561 (cond ((neq key
:allow-other-keys
)
562 (unless (find key allowed
:end n-allowed
)
563 (when (eq allow-other nil
)
565 (setq seen-unknown-key-p t
)))
566 ((eq allow-other
+none
+) ; = unseen so far
568 (return (check-odd-length tail n-visited
))
570 (when seen-unknown-key-p
572 (setq allow-other nil
)))))))))))
574 (declaim (ftype (sfunction (function) function
) interpreted-applicator
))
575 ;;; Get a parsed LAMBDA-FRAME from the proto-fn, reinstall a more specific
576 ;;; lambda applicator, and jump to it.
577 (defun interpreter-trampoline (fun &rest args
)
578 (setf (values (interpreted-function-frame fun
)
579 (interpreted-function-cookie fun
))
580 (proto-fn-frame (fun-proto-fn fun
) (interpreted-function-env fun
)))
581 (apply (setf (funcallable-instance-fun fun
) (interpreted-applicator fun
))
584 ;;; The most general case of interpreted function application.
585 ;;; All combinations of fancy args are allowed and any var can be special.
586 ;;; This is a ton of code to inline, but it uses the same concept as for
587 ;;; inlined %%EVAL - there is fast version and a slow version with extra
588 ;;; extra wrapping for when hooks are in use.
590 (define-symbol-macro *absent
* (%make-lisp-obj sb-vm
:unbound-marker-widetag
))
591 (declaim (maybe-inline apply-lambda
))
592 (defun apply-lambda (frame fun n-args args
)
593 (declare (list args
))
594 (let* ((values (make-array (lambda-frame-n-bound-vars frame
)))
595 (symbol-cells (cons (lambda-frame-min-args frame
)
596 (frame-symbols frame
)))
598 (if (lambda-frame-share-block-p frame
)
600 (interpreted-function-env fun
) values symbol-cells frame
601 (list (lambda-frame-block-name frame
)))
603 (interpreted-function-env fun
) values symbol-cells frame
)))
604 (special-b (frame-special-b frame
))
605 (specials (frame-specials frame
))
607 (1- (keyword-bits-n-keys (lambda-frame-keyword-bits frame
))))
610 (declare (index-or-minus-1 decoder-index
) (list tail
))
611 (labels ((instruction ()
612 (svref (frame-values frame
) (incf decoder-index
)))
613 (fancy-arg (&aux
(mode (the fixnum
(instruction))))
614 (case (logand mode
+arg-mode-mask
+)
616 (cond ((setq arg-supplied-p tail
)
617 (incf decoder-index
(logand mode
+has-default
+))
619 ((logtest mode
+has-default
+)
620 (dispatch (instruction) new-env
))))
622 (let* ((key (svref (frame-values frame
)
623 (argument-keyword-index mode
)))
624 (val (getf tail key
*absent
*)))
625 (cond ((setq arg-supplied-p
(neq val
*absent
*))
626 (incf decoder-index
(logand mode
+has-default
+))
628 ((logtest mode
+has-default
+)
629 (dispatch (instruction) new-env
)))))
630 (#.
+supplied-p-var
+ (if arg-supplied-p t nil
))
632 (if (logtest mode
+has-default
+)
633 (dispatch (instruction) new-env
)))
634 (#.
+rest-arg
+ tail
))))
635 (declare (inline instruction
))
637 (values (car symbol-cells
)
639 (fancy-arg) (binding-typechecks frame
)
640 frame-index
(frame-symbols frame
))
641 :specials
(pop specials
))
642 ;; form to start with
644 (values (lambda-frame-min-args frame
)
646 (if tail
(pop tail
) (err-too-few-args fun n-args
))
647 (binding-typechecks frame
)
648 frame-index
(frame-symbols frame
))
649 :specials
(pop specials
))
650 ;; maxargs/keywords should be checked now because it would be
651 ;; strange to eval some defaulting forms and then croak.
652 (cond ((logtest (lambda-frame-keyword-bits frame
) +keyp-bit
+)
654 (nthcdr (lambda-frame-n-optional frame
) tail
)
655 (lambda-frame-keyword-bits frame
)
656 (frame-values frame
)))
657 ((and (not (logtest (lambda-frame-keyword-bits frame
)
659 ;; FIXME: this call to LENGTH can be avoided by counting
660 ;; bindings made and subtracting from N-ARGS.
661 (> (length (truly-the list tail
))
662 (lambda-frame-n-optional frame
)))
663 (err-too-many-args fun n-args
)))
664 (let*-bind frame-index
(lambda-frame-n-bound-vars frame
)))
665 ;; done with sequential bindings
666 (setf (env-symbols new-env
) (frame-symbols frame
))
667 (enforce-types frame
(interpreted-function-env fun
))
668 ;; Three cases: no block, block and vars share the ENV,
669 ;; or allocate another ENV
670 (cond ((eql (lambda-frame-block-name frame
) 0)
671 (dispatch (lambda-frame-sexpr frame
) new-env
))
672 ((lambda-frame-share-block-p frame
)
673 (catch (lambda-env-block new-env
)
674 (dispatch (lambda-frame-sexpr frame
) new-env
)))
676 (let ((exit (list (lambda-frame-block-name frame
))))
678 (dispatch (lambda-frame-sexpr frame
)
679 (make-block-env new-env exit nil
680 *vacuous-decls
*))))))))))
682 (defun applicator/general
(fun)
684 (declare #.
+handler-optimize
+)
685 (declare (inline apply-lambda
))
686 (with-lambda-frame (frame fun
(apply #'interpreter-trampoline fun args
))
687 (apply-lambda frame fun
(length args
) args
))))
689 ;;; Positional applicator is for lambda-lists that do not use any
690 ;;; lambda-list keyword, perform no type checks and make no special bindings.
691 ;;; Choose the most efficient applicator based on N-args and
692 ;;; whether or not there is a block name. Since there are no defaulting forms,
693 ;;; the block name (if any) and variables can have the same extent.
694 ;;; User-supplied code could not detect the difference.
695 (defun applicator/positional
(fun)
697 ((new-env (constructor storage-cells
&rest more-args
)
698 `(,constructor
(interpreted-function-env fun
) ,storage-cells
699 (frame-symbols frame
) frame
,@more-args
))
700 (invoke (n &aux
(args (subseq '(arg1 arg2 arg3 arg4 arg5
) 0 n
)))
701 `(if (eql (lambda-frame-block-name (interpreted-function-frame fun
))
703 (named-lambda (.apply.
,n
) ,args
704 (declare #.
+handler-optimize
+ (optimize sb-c
:verify-arg-count
))
706 (frame fun
(interpreter-trampoline fun
,@args
))
707 (dispatch (lambda-frame-sexpr frame
)
708 (new-env make-var-env
709 ,(if (zerop n
) nil
`(vector ,@args
))))))
710 (named-lambda (.apply.
,n
) ,args
711 (declare #.
+handler-optimize
+ (optimize sb-c
:verify-arg-count
))
713 (frame fun
(interpreter-trampoline fun
,@args
))
714 (let ((exit (list (lambda-frame-block-name frame
))))
716 (dispatch (lambda-frame-sexpr frame
)
717 (new-env make-lambda-env
718 ,(if (zerop n
) nil
`(vector ,@args
))
720 (case (lambda-frame-min-args (interpreted-function-frame fun
))
731 (let* ((n-actual (length args
))
732 (excess (- n-actual
(lambda-frame-min-args frame
))))
733 (cond ((minusp excess
) (err-too-few-args fun n-actual
))
734 ((plusp excess
) (err-too-many-args fun n-actual
))))
735 (let ((cells (make-array (lambda-frame-n-bound-vars frame
))))
736 (dotimes (i (lambda-frame-min-args frame
) ,form
)
737 (setf (svref cells i
) (nth i args
)))))))
738 (if (eql (lambda-frame-block-name (interpreted-function-frame fun
)) 0)
739 (named-lambda (.apply.
) (&rest args
)
740 (declare #.
+handler-optimize
+)
742 (frame fun
(apply #'interpreter-trampoline fun args
))
743 (with-args (dispatch (lambda-frame-sexpr frame
)
744 (new-env make-var-env cells
)))))
745 (named-lambda (.apply.
) (&rest args
)
746 (declare #.
+handler-optimize
+)
748 (frame fun
(apply #'interpreter-trampoline fun args
))
750 (let ((exit (list (lambda-frame-block-name frame
))))
752 (dispatch (lambda-frame-sexpr frame
)
753 (new-env make-lambda-env cells
756 ;;; /&Optional applicator disallows &REST and &KEY because the stack arguments
757 ;;; are never listified (it's an implicit &MORE arg). I don't want to write code
758 ;;; to manually listify, nor hand-roll GETF. Also no special bindings permitted.
759 (defun applicator/&optional
(fun)
760 (named-lambda (.apply.
&optional
) (&rest args
)
761 (declare #.
+handler-optimize
+)
762 (with-lambda-frame (frame fun
(apply #'interpreter-trampoline fun args
))
763 (let* ((n-actual (let* ((min (lambda-frame-min-args frame
))
764 (max (+ min
(lambda-frame-n-optional frame
)))
767 (err-too-few-args fun n
))
769 (err-too-many-args fun n
))
771 (values (make-array (lambda-frame-n-bound-vars frame
)))
772 (symbol-cells (cons (lambda-frame-min-args frame
)
773 (frame-symbols frame
)))
775 (if (lambda-frame-share-block-p frame
)
777 (interpreted-function-env fun
) values symbol-cells frame
778 (list (lambda-frame-block-name frame
)))
780 (interpreted-function-env fun
) values symbol-cells frame
)))
784 (declare (index-or-minus-1 decoder-index arg-index
))
785 (with-let-bindings (values (lambda-frame-min-args frame
)
786 :value
(nth (incf arg-index
) args
) :specialp nil
)
787 nil
) ; empty body. no special bindings, so no PROGV
788 (flet ((instruction ()
789 (svref (frame-values frame
) (incf decoder-index
))))
790 (declare (inline instruction
))
792 (values (car symbol-cells
)
794 (let ((mode (the fixnum
(instruction))))
795 (case (logand mode
+arg-mode-mask
+)
797 (cond ((setq arg-supplied-p
(< (incf arg-index
) n-actual
))
798 (incf decoder-index
(logand mode
+has-default
+))
799 (nth arg-index args
))
800 ((logtest mode
+has-default
+)
801 (dispatch (instruction) new-env
))))
802 (#.
+supplied-p-var
+ (if arg-supplied-p t nil
))
803 (#.
+aux-var
+ (if (logtest mode
+has-default
+)
804 (dispatch (instruction) new-env
)))))
806 ;; form to start with
807 (let*-bind
(lambda-frame-min-args frame
)
808 (lambda-frame-n-bound-vars frame
))
809 ;; done with sequential bindings
810 (setf (env-symbols new-env
) (frame-symbols frame
))
811 ;; Three cases: no block, block and vars share the ENV,
812 ;; or allocate another ENV
813 (cond ((eql (lambda-frame-block-name frame
) 0)
814 (dispatch (lambda-frame-sexpr frame
) new-env
))
815 ((lambda-frame-share-block-p frame
)
816 (catch (lambda-env-block new-env
)
817 (dispatch (lambda-frame-sexpr frame
) new-env
)))
819 (let ((exit (list (lambda-frame-block-name frame
))))
821 (dispatch (lambda-frame-sexpr frame
)
822 (make-block-env new-env exit
823 nil
*vacuous-decls
*))))))))))))
825 (declaim (type (or null compiled-function
) *self-applyhook
*))
826 (defvar *self-applyhook
* nil
) ; not quite *applyhook* as outlined in CLtL
828 ;;; A trampoline which never installs a more-specific trampoline,
829 ;;; and checks for a binding of *SELF-APPLYHOOK* on each call.
830 (defun interpreter-hooked-trampoline (fun &rest args
)
831 (multiple-value-bind (frame cookie
)
832 (proto-fn-frame (fun-proto-fn fun
) (interpreted-function-env fun
))
833 (setf (values (interpreted-function-frame fun
)
834 (interpreted-function-cookie fun
)) (values frame cookie
))
835 ;; *SELF-APPLYHOOK* isn't the *APPLYHOOK* as described by CLtL.
836 ;; When bound, each hooked function will funcall the hook with
837 ;; itself and the arguments and a continuation of two arguments
838 ;; that the hook should call to actually perform the application.
839 ;; APPLY-LAMBDA is not inlined here. If you're using the hook,
840 ;; things are running at less than top speed anyway.
841 (if *self-applyhook
* ; must be a compiled-function
842 (funcall *self-applyhook
* fun args
844 (apply-lambda (interpreted-function-frame self
)
845 self
(length args
) args
)))
846 ;; Assuming the compiler is doing the right thing,
847 ;; this LENGTH is gotten from the passing location.
848 (apply-lambda frame fun
(length args
) args
))))
850 ;;; Compute the function that should be used when applying FUN.
851 ;;; This uses highly specialized code for small fixed N args <= 5,
852 ;;; and slightly more general code for any fixed number of args > 5.
853 ;;; Bound special arguments require the most general entry.
855 (defun interpreted-applicator (fun)
856 (let ((frame (interpreted-function-frame fun
)))
857 (if (and (zerop (frame-special-b frame
)) ; no bound specials
858 (not (logtest (lambda-frame-keyword-bits frame
) ; fixed upper bound
859 (logior +restp-bit
+ +keyp-bit
+))) ; on arg count
860 (eql (binding-typechecks frame
) +none
+)
861 (eql (extra-typechecks frame
) +none
+))
862 (if (zerop (length (frame-values frame
)))
863 (applicator/positional fun
)
864 (applicator/&optional fun
))
865 (applicator/general fun
))))
870 (defun get-thinginator () #'thing
)
871 (defun thing () 'the-thing
)
872 (funcall (get-thinginator)) ; returns THE-THING
873 (defmacro thing
() ''thing-macro
) ; system warns about this
874 (get-thinginator) ; errs - it correctly perceives the redefinition
877 ;;; Return T if SYMBOL might get redefined as a macro when it was previously
878 ;;; a function and vice versa. Extra checks are done on every use of the symbol
879 ;;; as a function name.
880 (defun fluid-def-p (symbol)
881 ;; Todo: add most system-internal packages here probably
882 (not (memq (symbol-package symbol
)
884 (mapcar #'find-package
'("CL" "SB-KERNEL" "SB-INT" "SB-IMPL"
885 "SB-C" "SB-VM" "SB-ALIEN" "SB-ALIEN-INTERNALS"
887 "SB-SYS" #+sb-thread
"SB-THREAD"))))))
890 * (defmacro baz
(n) `(nth ,n
*mumble
*))
891 * (define-symbol-macro mumble
(cdr (feep)))
892 * (defmacro feep
() '(aref *x
* 1))
893 * (nth-value 1 (tracing-macroexpand-1 '(shiftf (baz 3) (feep)) nil
))
894 => ((#<INTERPRETED-FUNCTION
(DEFMACRO BAZ
)> . BAZ
) (MUMBLE CDR
(FEEP))
895 (#<INTERPRETED-FUNCTION
(DEFMACRO FEEP
)> . FEEP
))
898 (defvar *show-macroexpansion
* nil
)
899 ;;; Expand FORM once, capturing all "interesting" expansions occuring within.
900 ;;; For example (INCF FOO) is a builtin macro whose functional definition is
901 ;;; not considered per se interesting, however if FOO is a symbol macro,
902 ;;; then the meaning of that form changes if FOO gets redefined.
904 ;;; This is still not powerful enough to work all the time - we really need to
905 ;;; know if anything so much as inquired whether a symbol is a macro.
906 ;;; Continuing the above example, if FOO is not a macro, then making it into
907 ;;; a macro later will have no effect, because there is no object that
908 ;;; stands for the identity of FOO as a macro. This is not a problem with
910 ;;; Also note that CLtL2 says
911 ;;; "macro definitions should not depend on the time at which they are expanded"
913 (defun tracing-macroexpand-1 (form env
&optional
(predicate #'fluid-def-p
)
914 &aux
(original-hook (valid-macroexpand-hook))
916 (unless (allow-macro-redefinition env
)
917 (return-from tracing-macroexpand-1
918 (values (macroexpand-1 form env
) nil
)))
919 (flet ((macroexpand-hook (function form env
)
920 (let ((expansion (funcall original-hook function form env
)))
922 ;; All global symbol-macros are recorded - there are no builtins
923 ;; which are candidates for removal. symbol-macrolet expansions
924 ;; aren't recorded, unless they happen to be EQ to a global
925 ;; expansion, which is unlikely and nothing to worry about.
926 (if (neq expansion
(info :variable
:macro-expansion form
))
927 nil
; I have no idea what to record
928 (push (cons form expansion
) expanders
))
929 ;; If the expander is EQ to the global one and the symbol
930 ;; satisfies the interestingness test.
931 (let* ((head (car form
)) (global-fn (macro-function head nil
)))
932 (if (and (eq function global-fn
) (funcall predicate head
))
933 (push (cons global-fn head
) expanders
))))
935 (let ((expansion (let ((*macroexpand-hook
* #'macroexpand-hook
))
936 (macroexpand-1 form env
))))
937 (setq expanders
(nreverse expanders
))
938 ;; condition on #+eval-show also?
939 (when *show-macroexpansion
*
940 (format t
"~&Expanded ~S~% into ~S~%~@[ using ~S~]~%"
941 form expansion expanders
))
942 (values expansion expanders
))))
944 ;;; Return T if the evaluator should always consider that macros
945 ;;; might be redefined. If NIL then cached expansions are permanent.
946 (defun allow-macro-redefinition (env)
947 (if (policy env
(and (= speed
3) (= debug
0) (= safety
0)))
951 (defun arglist-to-sexprs (args)
952 (let ((argc (or (list-length args
)
953 (ip-error "Malformed function call"))))
954 (values (mapcar #'%sexpr args
) argc
)))
956 ;;; Return a handler which decides whether its supplied SEXPR needs
957 ;;; to have macroexpansion performed again due to changes to global macros.
958 ;;; If not, just dispatch the previously computed expansion.
960 ;;; Just knowing the macroexpander isn't enough. We need to collect _all_
961 ;;; expanders that ran during 1 round of expansion, which can't be determined
962 ;;; without running the outermost and tracing what happens.
964 ;;; EXPANSION is a SEXPR for the overall result of expansion.
965 ;;; FNAME is the symbol at the head of the original form.
966 ;;; Each element of KEYS is (#<FUNCTION> . SYM) or (SYM . SYMBOL-EXPANSION)
967 ;;; The representation is unambiguous because a symbol is not a function,
968 ;;; whereas (SYM . EXPANSION|FUNCTION) is ambigious because through contortions
969 ;;; it is possible to have a symbol's expansion be a function object.
970 ;;; If any key is changed, restart using the original sexpr form.
972 (defun digest-macro-form (expansion fname keys
)
973 (if (and (endp (cdr keys
)) ; if one key
974 (let ((k (car keys
))) ; which is the function that we expect
975 (and (functionp (car k
)) (eq (cdr k
) fname
))))
976 ;; Assume that if MACRO-FUNCTION for the form's head is EQ to what it was
977 ;; previously, that it will produce the same expansion (in this ENV).
978 ;; This can of course is easily violated by nondeterministic macros.
979 (let ((macro-fn (caar keys
)))
980 (hlambda MACRO
/1 (fname macro-fn expansion
) (env old-sexpr
)
981 (if (eq (macro-function fname
) macro-fn
)
982 (dispatch expansion env
)
985 (format t
"~&Changed expander: ~S~%" fname
)
986 (digest-form (sexpr-form old-sexpr
) env old-sexpr
)))))
987 ;; Same as above but generalized to N keys.
988 (hlambda MACRO
+ (keys expansion
) (env old-sexpr
)
989 (if (every (lambda (k)
990 (if (functionp (car k
))
991 (eq (car k
) (macro-function (cdr k
)))
992 (eq (info :variable
:macro-expansion
(car k
))
995 (dispatch expansion env
)
998 (format t
"~&Changed expanders: ~S~%" keys
)
999 (digest-form (sexpr-form old-sexpr
) env old-sexpr
))))))
1002 (CASES n
(1 5 frob
) (4 (exceptional-case)) (t (fallback-case)))
1007 (4 (EXCEPTIONAL-CASE))
1009 (T (FALLBACK-CASE)))
1012 (defmacro cases
(test-var (min max template
) &rest specified-cases
)
1014 ,@(loop for i from min to max
1016 (or (assoc i specified-cases
)
1017 `(,i
(,template
,i
))))
1019 ,@(cdr (assoc t specified-cases
)))))
1021 ;;; A local-call uses LOCAL-FDEFINITION to obtain the function, which
1022 ;;; is *always* a function, never a macro and never undefined.
1023 ;;; Some clever macrology might share the handler-generator
1024 ;;; with DIGEST-GLOBAL-CALL
1025 (defun digest-local-call (frame-ptr args
&aux
(n-args 0))
1026 (multiple-value-setq (args n-args
) (arglist-to-sexprs args
))
1027 (macrolet ((funcall-n (n)
1028 `(hlambda (LOCAL-CALL ,N
) (data) (env)
1029 (funcall (local-fdefinition (svref data
0) env
)
1030 ,@(loop for i from
1 repeat n
1031 collect
`(dispatch (svref data
,i
) env
))))))
1032 (let ((data (if (> n-args
1) (coerce (cons frame-ptr args
) 'vector
))))
1033 (cases n-args
(0 5 funcall-n
)
1034 (0 (hlambda (LOCAL-CALL 0) (frame-ptr) (env)
1035 (funcall (local-fdefinition frame-ptr env
))))
1036 (1 (let ((arg (first args
)))
1037 (hlambda (LOCAL-CALL 1) (frame-ptr arg
) (env)
1038 (funcall (local-fdefinition frame-ptr env
) (dispatch arg env
)))))
1039 (t (hlambda LOCAL-CALL
(data) (env)
1040 (declare (simple-vector data
))
1041 (let* ((arglist (make-list (1- (length data
))))
1043 (dotimes (i (1- (length data
))
1044 (apply (local-fdefinition (svref data
0) env
)
1046 (rplaca tail
(dispatch (svref data
(1+ i
)) env
))
1049 ;;; Apply what is probably a function - it was when the form was digested.
1050 ;;; This carefully mimics the compiler's behavior of referencing the
1051 ;;; function only after evaluation of its args. In particular, supposing that
1052 ;;; BAZ is not defined, this works in compiled code:
1053 ;;; (DEFUN FOO () (BAZ (SETF (SYMBOL-FUNCTION 'BAZ) (LAMBDA (X) `(HI ,X)))))
1055 ;;; Interpreted code needs an explicit check for NIL in an fdefn-fun.
1056 ;;; Compiled code doesn't because the 'raw-addr' slot is always
1057 ;;; something valid to jump to.
1058 (defun apply-probably-fun (fdefinition args env
&aux
(n-args 0))
1059 (multiple-value-setq (args n-args
) (arglist-to-sexprs args
))
1062 (let* ((arg-names (subseq '(a b c d e
) 0 n
))
1064 (loop for arg in arg-names for i from
1 repeat n
1067 ,(if (= n
1) '(cdr data
) `(svref data
,i
))
1069 `(hlambda (GLOBAL-CALL ,n
) (data) (env sexpr
)
1070 (symbol-macrolet ((fdefn ,(case n
1073 (t '(svref data
0)))))
1075 (digest-form (sexpr-form sexpr
) env sexpr
)
1077 (funcall (sb-c:safe-fdefn-fun fdefn
) ,@arg-names
)))))))
1080 (0 (let ((data fdefinition
)) (funcall-n 0)))
1081 (1 (let ((data (cons fdefinition
(first args
)))) (funcall-n 1)))
1083 (let ((data (coerce (cons fdefinition args
) 'vector
)))
1084 (cases n-args
(2 5 funcall-n
)
1085 (t (hlambda GLOBAL-CALL
(data) (env sexpr
)
1086 (declare (simple-vector data
))
1087 (symbol-macrolet ((fdefn (svref data
0)))
1089 (digest-form (sexpr-form sexpr
) env sexpr
)
1090 (let* ((arglist (make-list (1- (length data
))))
1092 (dotimes (i (1- (length data
))
1093 (apply (sb-c:safe-fdefn-fun fdefn
) arglist
))
1094 (rplaca tail
(dispatch (svref data
(1+ i
)) env
))
1095 (pop tail
)))))))))))))
1096 (if (allow-macro-redefinition env
)
1097 (macrolet ((re-expand-p ()
1098 '(let ((f (fdefn-fun fdefn
)))
1099 (and f
(sb-impl::macro
/special-guard-fun-p f
)))))
1101 (macrolet ((re-expand-p () nil
)) (generate-switch)))))
1103 ;;; Evaluate the arguments to a function that can't be called,
1104 ;;; then call it. Very weird, yes! But this is reached in two situations:
1105 ;;; 1. the user wrote (funcall 'IF ...)
1106 ;;; 2. the user defined a new special operator that the interpreter
1107 ;;; does not know about.
1108 ;;; In either case %LOOKS-LIKE-MACRO-P will return T,
1109 ;;; because it knows that the fdefn-fun is an error-invoking trampoline.
1110 ;;; But there is no macroexpander, so we have to do "something".
1111 ;;; This handler is the way we punt, because the careful handler (above)
1112 ;;; would see that the thing to be applied is a guard trampoline,
1113 ;;; and would start over again at digest-global-call.
1115 ;;; Note also the subtle difference between these two:
1116 ;;; (funcall 'IF 'FOO 'BAR)
1117 ;;; (funcall #'IF ...)
1118 ;;; In the former, the FUNCALL is reached, because every argument
1119 ;;; to the funcall was legally evaluable. But in the latter, it is not
1120 ;;; reached since the first argument to funcall signals an error.
1121 (defun apply-definitely-not-fun (fname args
)
1122 (let ((data (coerce (cons fname
(arglist-to-sexprs args
)) 'vector
)))
1123 (hlambda GLOBAL-CALL
(data) (env)
1124 (declare (simple-vector data
))
1125 (let* ((arglist (make-list (1- (length data
))))
1127 ;; "unable to optimize apply"
1128 (declare (muffle-conditions compiler-note
))
1129 (dotimes (i (1- (length data
))
1130 (apply (the symbol
(svref data
0)) arglist
))
1131 (rplaca tail
(dispatch (svref data
(1+ i
)) env
))
1134 ;;; Handler is specialized only if the function is builtin.
1135 ;;; In such cases, reference the function directly, eliding the deref
1136 ;;; through an FDEFINITION.
1137 ;;; It can always be kicked out of the cache by touching the globaldb cookie.
1138 (defun digest-global-call (fname args env
)
1139 ;; For user-defined functions declared inline, don't bother
1140 ;; checking for being redefined as a macro.
1141 ;; The globaldb cookie will take care of redefinition.
1142 ;; (neq (info :function :inlinep fname) :inline))
1144 (when (symbolp fname
)
1145 (when (eq (info :function
:kind fname
) :special-form
)
1146 (return-from digest-global-call
1147 (apply-definitely-not-fun fname args
)))
1149 ;; Structure-accessor: interpreted accessors are *terrible*.
1150 ;; We could use a handler (need to respect NOTINLINE though),
1151 ;; or just COMPILE the accessor, since who's to say
1152 ;; that DEFSTRUCT doesn't somehow magically produce
1153 ;; compiled accessors via closures or a LAP assembler.
1154 ;; Frankly the latter ought to be possible.
1155 ;; And this doesn't fix the problem with SETF.
1156 (when (fboundp fname
)
1157 (let ((f (symbol-function fname
)))
1158 (when (and (interpreted-function-p f
)
1159 (structure-instance-accessor-p fname
))
1160 ;: Compile the accessor. If it was defined in a non-null environment,
1161 ;; conversion to a lexenv could say "too complex", so we want to
1162 ;; force it. Passing two arguments to COMPILE achieves this.
1163 ;; We can be confident that the expression doesn't need a lexenv,
1164 ;; because if the function were incompatible with the source-transform,
1165 ;; %DEFUN would have cleared the :source-transform, and fname would not
1166 ;; satisfy STRUCTURE-INSTANCE-ACCESSOR-P.
1167 #+nil
(format t
"~&; Interpreter: Compiling ~S~%" fname
)
1168 ;; FIXME: ensure that the compiled function is safe.
1169 (compile fname
(function-lambda-expression f
)))))
1171 (when (fluid-def-p fname
)
1172 ;; Return a handler that calls FNAME very carefully
1173 (return-from digest-global-call
1174 (apply-probably-fun (find-or-create-fdefn fname
) args env
))))
1176 ;; Try to recognize (FUNCALL constant-fun ...)
1177 ;; This syntax is required when using SETF functions, and it should
1178 ;; be no less efficient than (F args).
1179 ;; But, [FIXME?] can FUNCALL be rebound lexically?
1180 (when (and (eq fname
'funcall
)
1181 (not (endp args
)) ; FUNCALL demands at least one arg
1183 '(or (cons (eql function
)
1184 (cons (satisfies legal-fun-name-p
) null
))
1185 (cons (eql quote
) (cons symbol null
)))))
1186 (let* ((function-form (first args
))
1187 (fname (second function-form
)))
1188 ;; (FUNCALL 'SYMBOL args...) => (SYMBOL args...) without the lexenv.
1189 (when (eq (car function-form
) 'quote
)
1190 (return-from digest-global-call
1191 (digest-global-call fname
(cdr args
) env
)))
1193 ;; It's (FUNCALL #'FUNCTION ...)
1194 (let ((frame-ptr (local-fn-frame-ptr fname env
)))
1196 ((nil) ; global function (or special operator, which will barf on you)
1197 (when (symbolp fname
) (coerce fname
'function
)) ; for effect
1198 (return-from digest-global-call
1199 (digest-global-call fname
(cdr args
) env
)))
1200 (:macro
) ; do not process - let the FUNCTION operator complain
1201 (t (return-from digest-global-call
1202 (digest-local-call frame-ptr
(cdr args
))))))))
1205 (fun (fdefinition fname
)))
1206 (multiple-value-setq (args n-args
) (arglist-to-sexprs args
))
1208 ;; Fold if every arg when trivially constant and the function is foldable.
1209 ;; "trivially" means without needing propagation to decide that.
1210 (when (notany #'sexpr-p args
)
1211 (let ((info (info :function
:info fname
)))
1212 (when (and info
(sb-c::ir1-attributep
(sb-c::fun-info-attributes info
)
1214 (let ((values (multiple-value-list (apply fname args
))))
1215 (return-from digest-global-call
1216 (if (or (cdr values
) (null values
))
1217 (handler #'return-constant-values values
)
1218 (return-constant (first values
))))))))
1220 ;; Todo: redefining any function in one of the builtin packages should
1221 ;; increment the globaldb cookie to unmemoized stored #<FUNCTION> objects.
1222 ;; Btw, it's weird that FDEFINITION strips out tracing wrappers
1223 ;; since FDEFINITION is the canonical way to get the function given a
1224 ;; general name, and seems like it's supposed to be just the
1225 ;; straightforward generalization of SYMBOL-FUNCTION.
1226 (macrolet ((funcall-n (n)
1227 `(hlambda (FAST-GLOBAL-CALL ,n
) (data) (env)
1228 (funcall (the function
(svref data
0))
1229 ,@(loop for i from
1 repeat n collect
1230 `(dispatch (svref data
,i
) env
))))))
1231 (let ((data (if (> n-args
1) (coerce (cons fun args
) 'vector
))))
1232 (cases n-args
(0 5 funcall-n
)
1233 (0 (hlambda (FAST-GLOBAL-CALL 0) (fun) (env)
1234 (declare (ignore env
))
1235 (funcall (the function fun
))))
1236 (1 (let ((arg (first args
))
1237 (handler-fn (gethash fname
*unary-functions
*)))
1239 (handler handler-fn arg
)
1240 (hlambda (FAST-GLOBAL-CALL 1) (fun arg
) (env)
1241 (funcall (the function fun
) (dispatch arg env
))))))
1242 (2 (let ((handler-fn (gethash fname
*binary-functions
*)))
1244 (handler handler-fn
(cons (first args
) (second args
)))
1247 (hlambda GLOBAL-CALL
(data) (env)
1248 (declare (simple-vector data
))
1249 (let* ((arglist (make-list (1- (length data
)))) (tail arglist
))
1250 (dotimes (i (1- (length data
))
1251 (apply (the function
(svref data
0)) arglist
))
1252 (rplaca tail
(dispatch (svref data
(1+ i
)) env
))
1255 (defmethod print-object ((obj basic-env
) stream
)
1256 (print-unreadable-object (obj stream
:identity t
:type t
)
1258 (write-string (env-to-string obj
) stream
)))
1260 (defmethod print-object ((obj sexpr
) stream
)
1261 ;; It's very confusing to debug this code if sexprs are visibly indistinct
1262 ;; from their lists, but it looks more pleasing in backtraces.
1263 ;; Maybe need a toggle switch that is not one of the standard ones?
1265 (let ((string (write-to-string (sexpr-form obj
))))
1266 (format stream
"#<sexpr ~A... #x~X>"
1267 (subseq string
0 (min (length string
) 30))
1268 (get-lisp-obj-address obj
)))
1269 (write (sexpr-form obj
) :stream stream
)))