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

📄 c-call.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 2 页
字号:
         (args :more t))  (:results (results :more t))  (:temporary (:sc unsigned-reg :offset rax-offset :to :result) rax)  (:ignore results)  (:vop-var vop)  (:save-p t)  (:generator 0    ;; ABI: Direction flag must be clear on function entry. -- JES, 2006-01-20    (inst cld)    ;; ABI: AL contains amount of arguments passed in XMM registers    ;; for vararg calls.    (move-immediate rax                    (loop for tn-ref = args then (tn-ref-across tn-ref)                       while tn-ref                       count (eq (sb-name (sc-sb (tn-sc (tn-ref-tn tn-ref))))                                 'float-registers)))    (inst call function)    ;; To give the debugger a clue. XX not really internal-error?    (note-this-location vop :internal-error)))(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 rsp-tn))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 7) 7)))        (inst sub rsp-tn delta)))    ;; C stack must be 16 byte aligned    (inst and rsp-tn -16)    (move result rsp-tn)))(define-vop (dealloc-number-stack-space)  (:info amount)  (:generator 0    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 7) 7)))        (inst add rsp-tn delta)))))(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 rsp-tn)))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 7) 7)))        (inst mov temp              (make-ea :qword                       :disp (+ nil-value                                (static-symbol-offset '*alien-stack*)                                (ash symbol-tls-index-slot word-shift)                                (- other-pointer-lowtag))))        (inst sub (make-ea :qword :base thread-base-tn                           :scale 1 :index temp) delta)))    (load-tl-symbol-value result *alien-stack*))  #!-sb-thread  (:generator 0    (aver (not (location= result rsp-tn)))    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 7) 7)))        (inst sub (make-ea :qword                           :disp (+ nil-value                                    (static-symbol-offset '*alien-stack*)                                    (ash symbol-value-slot word-shift)                                    (- other-pointer-lowtag)))              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 7) 7)))        (inst mov temp              (make-ea :qword                       :disp (+ nil-value                                (static-symbol-offset '*alien-stack*)                                (ash symbol-tls-index-slot word-shift)                                (- other-pointer-lowtag))))        (inst add (make-ea :qword :base thread-base-tn :scale 1 :index temp)              delta))))  #!-sb-thread  (:generator 0    (unless (zerop amount)      (let ((delta (logandc2 (+ amount 7) 7)))        (inst add (make-ea :qword                           :disp (+ nil-value                                    (static-symbol-offset '*alien-stack*)                                    (ash symbol-value-slot word-shift)                                    (- other-pointer-lowtag)))              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));;; Callbacks#-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 result-type argument-types)  (labels ((make-tn-maker (sc-name)             (lambda (offset)               (make-random-tn :kind :normal                               :sc (sc-or-lose sc-name)                               :offset offset)))           (out-of-registers-error ()             (error "Too many arguments in callback")))    (let* ((segment (make-segment))           (rax rax-tn)           (rcx rcx-tn)           (rdi rdi-tn)           (rsi rsi-tn)           (rdx rdx-tn)           (rbp rbp-tn)           (rsp rsp-tn)           (xmm0 float0-tn)           ([rsp] (make-ea :qword :base rsp :disp 0))           ;; How many arguments have been copied           (arg-count 0)           ;; How many arguments have been copied from the stack           (stack-argument-count 0)           (gprs (mapcar (make-tn-maker 'any-reg) *c-call-register-arg-offsets*))           (fprs (mapcar (make-tn-maker 'double-reg)                         ;; Only 8 first XMM registers are used for                         ;; passing arguments                         (subseq *float-regs* 0 8))))      (assemble (segment)        ;; Make room on the stack for arguments.        (inst sub rsp (* n-word-bytes (length argument-types)))        ;; Copy arguments from registers to stack        (dolist (type argument-types)          (let ((integerp (not (alien-float-type-p type)))                ;; A TN pointing to the stack location where the                ;; current argument should be stored for the purposes                ;; of ENTER-ALIEN-CALLBACK.                (target-tn (make-ea :qword :base rsp                                   :disp (* arg-count                                            n-word-bytes)))                ;; A TN pointing to the stack location that contains                ;; the next argument passed on the stack.                (stack-arg-tn (make-ea :qword :base rsp                                       :disp (* (+ 1                                                   (length argument-types)                                                   stack-argument-count)                                                n-word-bytes))))            (incf arg-count)            (cond (integerp                   (let ((gpr (pop gprs)))                     ;; Argument not in register, copy it from the old                     ;; stack location to a temporary register.                     (unless gpr                       (incf stack-argument-count)                       (setf gpr temp-reg-tn)                       (inst mov gpr stack-arg-tn))                     ;; Copy from either argument register or temporary                     ;; register to target.                     (inst mov target-tn gpr)))                  ((or (alien-single-float-type-p type)                       (alien-double-float-type-p type))                   (let ((fpr (pop fprs)))                     (cond (fpr                            ;; Copy from float register to target location.                            (inst movq target-tn fpr))                           (t                            ;; Not in float register. Copy from stack to                            ;; temporary (general purpose) register, and                            ;; from there to the target location.                            (incf stack-argument-count)                            (inst mov temp-reg-tn stack-arg-tn)                            (inst mov target-tn temp-reg-tn)))))                  (t                   (bug "Unknown alien floating point type: ~S" type)))))        ;; arg0 to FUNCALL3 (function)        ;;        ;; 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 expect anyone        ;; to rebind the variable. -- JES, 2006-01-01        (inst mov rdi (+ nil-value (static-symbol-offset                                    'sb!alien::*enter-alien-callback*)))        (loadw rdi rdi symbol-value-slot other-pointer-lowtag)        ;; arg0 to ENTER-ALIEN-CALLBACK (trampoline index)        (inst mov rsi (fixnumize index))        ;; arg1 to ENTER-ALIEN-CALLBACK (pointer to argument vector)        (inst mov rdx rsp)        ;; add room on stack for return value        (inst sub rsp 8)        ;; arg2 to ENTER-ALIEN-CALLBACK (pointer to return value)        (inst mov rcx rsp)        ;; Make new frame        (inst push rbp)        (inst mov  rbp rsp)        ;; Call        (inst mov  rax (foreign-symbol-address "funcall3"))        (inst call rax)        ;; Back! Restore frame        (inst mov rsp rbp)        (inst pop rbp)        ;; Result now on top of stack, put it in the right register        (cond          ((or (alien-integer-type-p result-type)               (alien-pointer-type-p result-type)               (alien-type-= #.(parse-alien-type 'system-area-pointer nil)                             result-type))           (inst mov rax [rsp]))          ((or (alien-single-float-type-p result-type)               (alien-double-float-type-p result-type))           (inst movq xmm0 [rsp]))          ((alien-void-type-p result-type))          (t           (error "unrecognized alien type: ~A" result-type)))        ;; Pop the arguments and the return value from the stack to get        ;; the return address at top of stack.        (inst add rsp (* (1+ (length argument-types)) n-word-bytes))        ;; Return        (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 + -