Tmux etc
This commit is contained in:
parent
276853ba84
commit
1cb167b597
361 changed files with 77302 additions and 4 deletions
|
|
@ -0,0 +1,132 @@
|
|||
July 2005
|
||||
These details were kindly provided by Duane Rettig of Franz.
|
||||
|
||||
Regarding the following snippet of the macro expansion of
|
||||
FF:DEF-FOREIGN-CALL:
|
||||
|
||||
(SYSTEM::FF-FUNCALL
|
||||
(LOAD-TIME-VALUE (EXCL::DETERMINE-FOREIGN-ADDRESS
|
||||
'("foo" :LANGUAGE :C) 2 NIL))
|
||||
'(:INT (INTEGER * *)) ARG1
|
||||
'(:DOUBLE (DOUBLE-FLOAT * *)) ARG2
|
||||
'(:INT (INTEGER * *)))
|
||||
|
||||
"
|
||||
... in Allegro CL, if you define a foreign call FOO with C entry point
|
||||
"foo" and with :call-direct t in the arguments, and if other things are
|
||||
satisfied, then if a lisp function BAR is compiled which has a call to
|
||||
FOO, that call will not go through ff-funcall (and thus a large amount
|
||||
of argument manipulation and processing) but will instead set up its
|
||||
arguments directly on the stack, and will then perform the "call" more
|
||||
or less directly, through the "entry vec" (a small structure which
|
||||
keeps track of a foreign entry's address and status)."
|
||||
|
||||
This is the code that generates what the compiler expects to see:
|
||||
|
||||
(setq call-direct-form
|
||||
(if* call-direct
|
||||
then `(setf (get ',lispname 'sys::direct-ff-call)
|
||||
(list ',external-name
|
||||
,callback
|
||||
,convention
|
||||
',returning
|
||||
',arg-types
|
||||
,arg-checking
|
||||
,entry-vec-flags))
|
||||
else `(remprop ',lispname 'sys::direct-ff-call)))
|
||||
|
||||
Thus generating something like:
|
||||
|
||||
(EVAL-WHEN (COMPILE LOAD EVAL)
|
||||
(SETF (GET 'FOO 'SYSTEM::DIRECT-FF-CALL)
|
||||
(LIST '("foo" :LANGUAGE :C) T :C
|
||||
'(:INT (INTEGER * *))
|
||||
'((:INT (INTEGER * *))
|
||||
(:FLOAT (SINGLE-FLOAT * *)))
|
||||
T
|
||||
2 ; this magic value is explained later
|
||||
)))
|
||||
|
||||
"
|
||||
(defun determine-foreign-address (name &optional (flags 0) method-index)
|
||||
;; return an entry-vec struct suitable for the foreign-call of name.
|
||||
;;
|
||||
;; name is either a string, which is taken without conversion, or
|
||||
;; a list consisting of a string to convert or a conversion function
|
||||
;; call.
|
||||
;; flags is an integer representing the flags to place into the entry-vec.
|
||||
;; method-index, if non-nil, is a word-index into a vtbl (virtual table).
|
||||
;; If method-index is true, then the name must be a string uniquely
|
||||
;; represented by the index and by the flags field.
|
||||
|
||||
Note that not all architectures implement the :method-index argument
|
||||
to def-foreign-call, but your interface likely won't support it
|
||||
anyway, so just leave it nil. As for the flags, they are constants
|
||||
stored into the entry-vec returned by d-f-a and are given here:
|
||||
|
||||
(defconstant ep-flag-call-semidirect 1) ; Real address stored in alt-address slot
|
||||
(defconstant ep-flag-never-release 2) ; Never release the heap
|
||||
(defconstant ep-flag-always-release 4) ; Always release the heap
|
||||
(defconstant ep-flag-release-when-ok 8) ; Release the heap unless without-interrupts
|
||||
|
||||
(defconstant ep-flag-tramp-calls #x70) ; Make calls through special trampolines
|
||||
(defconstant ep-flag-tramp-shift 4)
|
||||
|
||||
(defconstant ep-flag-variable-address #x100) ; Entry-point contains address of C var
|
||||
(defconstant ep-flag-strings-convert #x200) ; Convert strings automatically
|
||||
|
||||
(defconstant ep-flag-get-errno #x1000) ;; [rfe5060]: Get errno value after call
|
||||
(defconstant ep-flag-get-last-error #x2000) ;; [rfe5060]: call GetLastError after call
|
||||
;; Leave #x4000 and #x8000 open for expansion
|
||||
|
||||
Mostly, you'll give the value 2 (never release the heap), but if you
|
||||
give 4 or 8, then d-f-a will automatically set the 1 bit as well,
|
||||
which takes the call through a heap-release/reacquire process.
|
||||
|
||||
Some docs for entry-vec are:
|
||||
|
||||
;; -- entry vec --
|
||||
;; An entry-vec is an entry-point descriptor, usually a pointer into
|
||||
;; a shared-library. It is represented as a 5-element struct of type
|
||||
;; foreign-vector. The reason for this represntation is
|
||||
;; that it allows the entry point to be stored in a table, called
|
||||
;; the .saved-entry-points. table, and to be used by a foreign
|
||||
;; function. When the location of the foreign function to which the entry
|
||||
;; point refers changes, it is simply a matter of changing the value in entry
|
||||
;; point vector and the foreign call code sees it immediately. There is
|
||||
;; even an address that can be put in the entry point vector that denotes
|
||||
;; a missing foreign function, thus lookup can happen dynamically.
|
||||
|
||||
(defstruct (entry-vec
|
||||
(:type (vector excl::foreign (*)))
|
||||
(:constructor make-entry-vec-boa ()))
|
||||
name ; entry point name
|
||||
(address 0) ; jump address for foreign code
|
||||
(handle 0) ; shared-lib handle
|
||||
(flags 0) ; ep-* flags
|
||||
(alt-address 0) ; sometimes holds the real func addr
|
||||
)
|
||||
|
||||
[...]
|
||||
"
|
||||
|
||||
Regarding the arguments to SYSTEM::FF-FUNCALL:
|
||||
'(:int (integer * *)) argN
|
||||
|
||||
"The type-spec is as it is given in the def-foreign-call
|
||||
syntax, with a C type optionally followed by a lisp type,
|
||||
followed optionally by a user-conversion function name[...]"
|
||||
|
||||
|
||||
Getting the alignment:
|
||||
|
||||
CL-USER(2): (ff:get-foreign-type :int)
|
||||
#S(FOREIGN-FUNCTIONS::IFOREIGN-TYPE
|
||||
:ATTRIBUTES NIL
|
||||
:SFTYPE
|
||||
#S(FOREIGN-FUNCTIONS::SIZED-FTYPE-PRIM
|
||||
:KIND :INT
|
||||
:WIDTH 4
|
||||
:OFFSET 0
|
||||
:ALIGN 4)
|
||||
...)
|
||||
Loading…
Add table
Add a link
Reference in a new issue