X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fsysmacs.lisp;h=b9e44361e945e868efef34d56a3a80cdd7d87035;hb=b8f63d9b4e978bec3bfc1f4fc471e5ed946781fd;hp=d485246cae9f3d6662f664f2fd8ef213e3737f5f;hpb=a530bbe337109d898d5b4a001fc8f1afa3b5dc39;p=sbcl.git diff --git a/src/code/sysmacs.lisp b/src/code/sysmacs.lisp index d485246..b9e4436 100644 --- a/src/code/sysmacs.lisp +++ b/src/code/sysmacs.lisp @@ -11,38 +11,44 @@ (in-package "SB!IMPL") -(file-comment - "$Header$") - ;;; This checks to see whether the array is simple and the start and ;;; end are in bounds. If so, it proceeds with those values. -;;; Otherwise, it calls %WITH-ARRAY-DATA. Note that there is a -;;; DERIVE-TYPE method for %WITH-ARRAY-DATA. -(defmacro with-array-data (((data-var array &key (offset-var (gensym))) +;;; Otherwise, it calls %WITH-ARRAY-DATA. Note that %WITH-ARRAY-DATA +;;; may be further optimized. +;;; +;;; Given any ARRAY, bind DATA-VAR to the array's data vector and +;;; START-VAR and END-VAR to the start and end of the designated +;;; portion of the data vector. SVALUE and EVALUE are any start and +;;; end specified to the original operation, and are factored into the +;;; bindings of START-VAR and END-VAR. OFFSET-VAR is the cumulative +;;; offset of all displacements encountered, and does not include +;;; SVALUE. +(defmacro with-array-data (((data-var array &key offset-var) (start-var &optional (svalue 0)) (end-var &optional (evalue nil))) &body forms) - #!+sb-doc - "Given any Array, binds Data-Var to the array's data vector and Start-Var and - End-Var to the start and end of the designated portion of the data vector. - Svalue and Evalue are any start and end specified to the original operation, - and are factored into the bindings of Start-Var and End-Var. Offset-Var is - the cumulative offset of all displacements encountered, and does not - include Svalue." (once-only ((n-array array) (n-svalue `(the index ,svalue)) (n-evalue `(the (or index null) ,evalue))) - `(multiple-value-bind (,data-var ,start-var ,end-var ,offset-var) + `(multiple-value-bind (,data-var + ,start-var + ,end-var + ,@(when offset-var `(,offset-var))) (if (not (array-header-p ,n-array)) (let ((,n-array ,n-array)) (declare (type (simple-array * (*)) ,n-array)) ,(once-only ((n-len `(length ,n-array)) (n-end `(or ,n-evalue ,n-len))) `(if (<= ,n-svalue ,n-end ,n-len) + ;; success (values ,n-array ,n-svalue ,n-end 0) - (%with-array-data ,n-array ,n-svalue ,n-evalue)))) + ;; failure: Make a NOTINLINE call to + ;; %WITH-ARRAY-DATA with our bad data + ;; to cause the error to be signalled. + (locally + (declare (notinline %with-array-data)) + (%with-array-data ,n-array ,n-svalue ,n-evalue))))) (%with-array-data ,n-array ,n-svalue ,n-evalue)) - (declare (ignorable ,offset-var)) ,@forms))) #!-gengc