Skip to content

Commit df8b9a5

Browse files
committed
Added cmpname to provide compute-init-name
to asdf
1 parent 2f750c4 commit df8b9a5

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

src/lisp/kernel/build_files.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def aclasp(wrappers):
6767
"src/lisp/kernel/cmp/compile-file",
6868
"src/lisp/kernel/cmp/disassemble",
6969
"src/lisp/kernel/cmp/external-clang",
70+
"src/lisp/kernel/cmp/cmpname",
7071
"src/lisp/kernel/cmp/cmpbundle",
7172
"src/lisp/kernel/cmp/cmprepl",
7273
"src/lisp/kernel/tag/min-pre-epilogue",

src/lisp/kernel/cmp/cmpname.lsp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
(in-package :c)
2+
3+
4+
(defun encode-number-in-name (number)
5+
;; Encode a number in an alphanumeric identifier which is a valid C name.
6+
(declare (si::c-local))
7+
(cond ((zerop number) "0")
8+
((minusp number) (encode-number-in-name (- number)))
9+
(t
10+
(do* ((code "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
11+
(base (length code))
12+
(output '())
13+
(digit 0))
14+
((zerop number) (coerce (nreverse output) 'base-string))
15+
(multiple-value-setq (number digit) (floor number base))
16+
(push (char code digit) output)))))
17+
18+
19+
20+
(defun unique-init-name (file)
21+
"Create a unique name for this initialization function. The current algorithm
22+
relies only on the name of the source file and the time at which it is built. This
23+
should be enough to prevent name collisions for object files built in the same
24+
machine."
25+
(let* ((path (pathname file))
26+
(path-hash (logxor (ash (sxhash path) 8)
27+
(ash (sxhash (cddr (pathname-directory path))) 16)
28+
(sxhash (pathname-name path))))
29+
(seconds (get-universal-time))
30+
(ms (+ (* seconds 1000)
31+
(mod (floor (* 1000 (get-internal-real-time))
32+
internal-time-units-per-second)
33+
1000)))
34+
(tag (concatenate 'base-string
35+
"_clasp"
36+
(encode-number-in-name path-hash)
37+
"_"
38+
(encode-number-in-name ms))))
39+
tag))
40+
41+
(defun compute-init-name (pathname &key (kind (guess-kind pathname))
42+
(prefix nil)
43+
(wrapper nil))
44+
"Computes initialization function name. Libraries, FASLS and
45+
programs init function names can't be randomized to allow
46+
initialization from the C code which wants to use it."
47+
(let ((filename (pathname-name (translate-logical-pathname pathname)))
48+
(unique-name (unique-init-name pathname)))
49+
(case kind
50+
((:object :c)
51+
unique-name)
52+
((:fasl :fas)
53+
(init-function-name "CODE" :kind :fas :prefix prefix))
54+
((:static-library :lib)
55+
(init-function-name (if wrapper
56+
(remove-prefix +static-library-prefix+ filename)
57+
unique-name)
58+
:kind :lib
59+
:prefix prefix))
60+
((:shared-library :dll)
61+
(init-function-name (if wrapper
62+
(remove-prefix +shared-library-prefix+ filename)
63+
unique-name)
64+
:kind :dll
65+
:prefix prefix))
66+
((:program)
67+
(concatenate 'string (or prefix "init_") "CLASP_PROGRAM"))
68+
(otherwise
69+
(error "C::BUILDER cannot accept files of kind ~s" kind)))))
70+
71+
(defun init-function-name (s &key (kind :object) (prefix nil))
72+
(flet ((translate-char (c)
73+
(cond ((and (char>= c #\a) (char<= c #\z))
74+
(char-upcase c))
75+
((and (char>= c #\A) (char<= c #\Z))
76+
c)
77+
((or (eq c #\-) (eq c #\_))
78+
#\_)
79+
((eq c #\*)
80+
#\x)
81+
((eq c #\?)
82+
#\a)
83+
((digit-char-p c)
84+
c)
85+
(t
86+
#\p)))
87+
(disambiguation (c)
88+
(case kind
89+
((:object :c) "")
90+
((:fasl :fas) "fas_")
91+
((:library :static-library :lib) "lib_")
92+
((:shared-library :dll) "dll_")
93+
((:program) "exe_")
94+
(otherwise (error "Not a valid argument to INIT-FUNCTION-NAME: kind = ~S"
95+
kind)))))
96+
(setq s (map 'string #'translate-char (string s)))
97+
(concatenate 'string
98+
(or prefix "init_")
99+
(disambiguation kind)
100+
(map 'string #'translate-char (string s)))))
101+

0 commit comments

Comments
 (0)