]> gitweb.factorcode.org Git - factor.git/blob - basis/alien/data/data.factor
1a573888f1d08ef9c0d25663b680521755958032
[factor.git] / basis / alien / data / data.factor
1 ! (c)2009, 2010 Slava Pestov, Joe Groff bsd license
2 USING: accessors alien alien.arrays alien.c-types alien.strings
3 arrays byte-arrays combinators combinators.short-circuit
4 cpu.architecture fry generalizations io io.streams.memory kernel
5 libc locals macros math math.functions parser sequences
6 stack-checker.dependencies summary words ;
7 IN: alien.data
8
9 : <ref> ( value c-type -- c-ptr )
10     [ heap-size (byte-array) ] keep
11     '[ 0 _ set-alien-value ] keep ; inline
12
13 : deref ( c-ptr c-type -- value )
14     [ 0 ] dip alien-value ; inline
15
16 : little-endian? ( -- ? ) 1 int <ref> char deref 1 = ; foldable
17
18 GENERIC: c-array-constructor ( c-type -- word ) foldable
19
20 GENERIC: c-(array)-constructor ( c-type -- word ) foldable
21
22 GENERIC: c-direct-array-constructor ( c-type -- word ) foldable
23
24 GENERIC: c-array-type ( c-type -- word ) foldable
25
26 GENERIC: c-array-type? ( c-type -- word ) foldable
27
28 GENERIC: c-array? ( obj c-type -- ? ) foldable
29
30 M: word c-array?
31     c-array-type? execute( seq -- array ) ; inline
32
33 M: pointer c-array?
34     drop void* c-array? ;
35
36 GENERIC: >c-array ( seq c-type -- array )
37
38 M: word >c-array
39     c-array-type new clone-like ; inline
40
41 M: pointer >c-array
42     drop void* >c-array ;
43
44 GENERIC: <c-array> ( len c-type -- array )
45
46 M: word <c-array>
47     c-array-constructor execute( len -- array ) ; inline
48
49 M: pointer <c-array>
50     drop void* <c-array> ;
51
52 GENERIC: (c-array) ( len c-type -- array )
53
54 M: word (c-array)
55     c-(array)-constructor execute( len -- array ) ; inline
56
57 M: pointer (c-array)
58     drop void* (c-array) ;
59
60 GENERIC: <c-direct-array> ( alien len c-type -- array )
61
62 M: word <c-direct-array>
63     c-direct-array-constructor execute( alien len -- array ) ; inline
64
65 M: pointer <c-direct-array>
66     drop void* <c-direct-array> ;
67
68 SYNTAX: c-array{ \ } [ unclip >c-array ] parse-literal ;
69
70 SYNTAX: c-array@
71     scan-object [ scan-object scan-object ] dip
72     <c-direct-array> suffix! ;
73
74 ERROR: bad-byte-array-length byte-array type ;
75
76 M: bad-byte-array-length summary
77     drop "Byte array length doesn't divide type width" ;
78
79 : cast-array ( byte-array c-type -- array )
80     [ binary-object ] dip [ heap-size /mod 0 = ] keep swap
81     [ <c-direct-array> ] [ bad-byte-array-length ] if ; inline
82
83 : malloc-array ( n c-type -- array )
84     [ heap-size calloc ] [ <c-direct-array> ] 2bi ; inline
85
86 : malloc-like ( seq c-type -- malloc )
87     [ dup length ] dip malloc-array [ 0 swap copy ] keep ;
88
89 : malloc-byte-array ( byte-array -- alien )
90     binary-object [ nip malloc dup ] 2keep memcpy ;
91
92 : memory>byte-array ( alien len -- byte-array )
93     [ nip (byte-array) dup ] 2keep memcpy ;
94
95 : malloc-string ( string encoding -- alien )
96     string>alien malloc-byte-array ;
97
98 M:: memory-stream stream-read-unsafe ( n buf stream -- count )
99     stream alien>> :> src
100     buf src n memcpy
101     n src <displaced-alien> stream alien<<
102     n ; inline
103
104 M: value-type c-type-rep drop int-rep ;
105
106 M: value-type c-type-getter
107     drop [ swap <displaced-alien> ] ;
108
109 M: value-type c-type-copier
110     heap-size '[ _ memory>byte-array ] ;
111
112 M: value-type c-type-setter
113     [ c-type-getter ] [ heap-size ] bi '[ @ swap _ memcpy ] ;
114
115 M: array c-type-boxer-quot
116     unclip [ array-length ] dip [ <c-direct-array> ] 2curry ;
117
118 M: array c-type-unboxer-quot drop [ >c-ptr ] ;
119
120 ERROR: local-allocation-error ;
121
122 <PRIVATE
123
124 : (local-allot) ( size align -- alien ) local-allocation-error ;
125
126 : (cleanup-allot) ( -- )
127     ! Inhibit TCO in order for the last word in the quotation
128     ! to still be able to access scope-allocated data.
129     ;
130
131 MACRO: (simple-local-allot) ( c-type -- quot )
132     [ add-depends-on-c-type ]
133     [ dup '[ _ heap-size _ c-type-align (local-allot) ] ] bi ;
134
135 : [hairy-local-allot] ( c-type initial -- quot )
136     over '[ _ (simple-local-allot) _ over 0 _ set-alien-value ] ;
137
138 : hairy-local-allot? ( obj -- ? )
139     {
140         [ array? ]
141         [ length 3 = ]
142         [ second initial: eq? ]
143     } 1&& ;
144
145 MACRO: (hairy-local-allot) ( obj -- quot )
146     dup hairy-local-allot?
147     [ first3 nip [hairy-local-allot] ]
148     [ '[ _ (simple-local-allot) ] ]
149     if ;
150
151 MACRO: (local-allots) ( c-types -- quot )
152     [ '[ _ (hairy-local-allot) ] ] map [ ] join ;
153
154 MACRO: box-values ( c-types -- quot )
155     [ c-type-boxer-quot ] map '[ _ spread ] ;
156
157 MACRO: out-parameters ( c-types -- quot )
158     [ dup hairy-local-allot? [ first ] when ] map
159     [ length ] [ [ '[ 0 _ alien-copy-value ] ] map ] bi
160     '[ _ nkeep _ spread ] ;
161
162 PRIVATE>
163
164 : with-scoped-allocation ( c-types quot -- )
165     [ [ (local-allots) ] [ box-values ] bi ] dip call
166     (cleanup-allot) ; inline
167
168 : with-out-parameters ( c-types quot -- values... )
169     [ drop (local-allots) ] [ swap out-parameters ] 2bi
170     (cleanup-allot) ; inline
171
172 GENERIC: binary-zero? ( value -- ? )
173
174 M: object binary-zero? drop f ; inline
175 M: f binary-zero? drop t ; inline
176 M: integer binary-zero? zero? ; inline
177 M: math:float binary-zero? double>bits zero? ; inline
178 M: complex binary-zero? >rect [ binary-zero? ] both? ; inline