⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-call.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 2 页
字号:
  (:generator 2   (inst mov res (make-fixup foreign-symbol :foreign-dataref))))(define-vop (call-out)  (:args (function :scs (sap-reg))         (args :more t))  (:results (results :more t))  (:temporary (:sc unsigned-reg :offset eax-offset                   :from :eval :to :result) eax)  (:temporary (:sc unsigned-reg :offset ecx-offset                   :from :eval :to :result) ecx)  (:temporary (:sc unsigned-reg :offset edx-offset                   :from :eval :to :result) edx)  (:node-var node)  (:vop-var vop)  (:save-p t)  (:ignore args ecx edx)  (:generator 0    ;; FIXME & OAOOM: This is brittle and error-prone to maintain two    ;; instances of the same logic, on in arch-assem.S, and one in    ;; c-call.lisp. If you modify this, modify that one too...    (cond ((policy node (> space speed))           (move eax function)           (inst call (make-fixup "call_into_c" :foreign)))          (t           ;; Setup the NPX for C; all the FP registers need to be           ;; empty; pop them all.           (dotimes (i 8)             (inst fstp fr0-tn))           ;; Clear out DF: Darwin, Windows, and Solaris at least require           ;; this, and it should not hurt others either.           (inst cld)           (inst call function)           ;; To give the debugger a clue. FIXME: not really internal-error?           (note-this-location vop :internal-error)           ;; Restore the NPX for lisp; ensure no regs are empty           (dotimes (i 7)             (inst fldz))           (if (and results                    (location= (tn-ref-tn results) fr0-tn))               ;; The return result is in fr0.               (inst fxch fr7-tn)       ; move the result back to fr0               (inst fldz))             ; insure no regs are empty           ))));;; While SBCL uses the FPU in 53-bit mode, most C libraries assume that;;; the FPU is in 64-bit mode. So we change the FPU mode to 64-bit with;;; the SET-FPU-WORD-FOR-C VOP before calling out to C and set it back;;; to 53-bit mode after coming back using the SET-FPU-WORD-FOR-LISP VOP.(define-vop (set-fpu-word-for-c)  (:node-var node)  (:generator 0    (when (policy node (= sb!c::float-accuracy 3))      (inst sub esp-tn 4)      (inst fnstcw (make-ea :word :base esp-tn))      (inst wait)      (inst or (make-ea :word :base esp-tn) #x300)      (inst fldcw (make-ea :word :base esp-tn))      (inst wait))))(define-vop (set-fpu-word-for-lisp)  (:node-var node)  (:generator 0    (when (policy node (= sb!c::float-accuracy 3))      (inst fnstcw (make-ea :word :base esp-tn))      (inst wait)      (inst and (make-ea :word :base esp-tn) #xfeff)      (inst fldcw (make-ea :word :base esp-tn))      (inst wait)      (inst add esp-tn 4))))(define-vop (alloc-number-stack-space)  (:info amount)  (:results (result :scs (sap-reg any-reg)))  (:result-types system-area-pointer)  (:generator 0    (aver (location= result esp-tn))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 3) 3)))        (inst sub esp-tn delta)))    (align-stack-pointer esp-tn)    (move result esp-tn)))(define-vop (alloc-alien-stack-space)  (:info amount)  #!+sb-thread (:temporary (:sc unsigned-reg) temp)  (:results (result :scs (sap-reg any-reg)))  (:result-types system-area-pointer)  #!+sb-thread  (:generator 0    (aver (not (location= result esp-tn)))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 3) 3)))        (inst mov temp              (make-ea-for-symbol-tls-index *alien-stack*))        (inst sub (make-ea :dword :base temp) delta :fs)))    (load-tl-symbol-value result *alien-stack*))  #!-sb-thread  (:generator 0    (aver (not (location= result esp-tn)))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 3) 3)))        (inst sub (make-ea-for-symbol-value *alien-stack*)              delta)))    (load-symbol-value result *alien-stack*)))(define-vop (dealloc-alien-stack-space)  (:info amount)  #!+sb-thread (:temporary (:sc unsigned-reg) temp)  #!+sb-thread  (:generator 0    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 3) 3)))        (inst mov temp              (make-ea-for-symbol-tls-index *alien-stack*))        (inst add (make-ea :dword :base temp) delta :fs))))  #!-sb-thread  (:generator 0    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 3) 3)))        (inst add (make-ea-for-symbol-value *alien-stack*)              delta)))));;; not strictly part of the c-call convention, but needed for the;;; WITH-PINNED-OBJECTS macro used for "locking down" lisp objects so;;; that GC won't move them while foreign functions go to work.(define-vop (touch-object)  (:translate touch-object)  (:args (object))  (:ignore object)  (:policy :fast-safe)  (:arg-types t)  (:generator 0))#-sb-xc-host(defun alien-callback-accessor-form (type sp offset)  `(deref (sap-alien (sap+ ,sp ,offset) (* ,type))))#-sb-xc-host(defun alien-callback-assembler-wrapper (index return-type arg-types)  "Cons up a piece of code which calls call-callback with INDEX and apointer to the arguments."  (declare (ignore arg-types))  (let* ((segment (make-segment))         (eax eax-tn)         (edx edx-tn)         (ebp ebp-tn)         (esp esp-tn)         ([ebp-8] (make-ea :dword :base ebp :disp -8))         ([ebp-4] (make-ea :dword :base ebp :disp -4)))    (assemble (segment)              (inst push ebp)                       ; save old frame pointer              (inst mov  ebp esp)                   ; establish new frame              (inst mov  eax esp)                   ;              (inst sub  eax 8)                     ; place for result              (inst push eax)                       ; arg2              (inst add  eax 16)                    ; arguments              (inst push eax)                       ; arg1              (inst push (ash index 2))             ; arg0              ;; Indirect the access to ENTER-ALIEN-CALLBACK through              ;; the symbol-value slot of SB-ALIEN::*ENTER-ALIEN-CALLBACK*              ;; to ensure it'll work even if the GC moves ENTER-ALIEN-CALLBACK.              ;; Skip any SB-THREAD TLS magic, since we don't expecte anyone              ;; to rebind the variable. -- JES, 2006-01-01              (load-symbol-value eax sb!alien::*enter-alien-callback*)              (inst push eax) ; function              (inst mov  eax (foreign-symbol-address "funcall3"))              (inst call eax)              ;; now put the result into the right register              (cond                ((and (alien-integer-type-p return-type)                      (eql (alien-type-bits return-type) 64))                 (inst mov eax [ebp-8])                 (inst mov edx [ebp-4]))                ((or (alien-integer-type-p return-type)                     (alien-pointer-type-p return-type)                     (alien-type-= #.(parse-alien-type 'system-area-pointer nil)                                   return-type))                 (inst mov eax [ebp-8]))                ((alien-single-float-type-p return-type)                 (inst fld  [ebp-8]))                ((alien-double-float-type-p return-type)                 (inst fldd [ebp-8]))                ((alien-void-type-p return-type))                (t                 (error "unrecognized alien type: ~A" return-type)))              (inst mov esp ebp)                   ; discard frame              (inst pop ebp)                       ; restore frame pointer              (inst ret))    (finalize-segment segment)    ;; Now that the segment is done, convert it to a static    ;; vector we can point foreign code to.    (let ((buffer (sb!assem::segment-buffer segment)))      (make-static-vector (length buffer)                          :element-type '(unsigned-byte 8)                          :initial-contents buffer))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -