]> gitweb.factorcode.org Git - factor.git/blob - core/generator/fixup/fixup.factor
Builtinn types now use new slot accessors; tuple slot type declaration work in progress
[factor.git] / core / generator / fixup / fixup.factor
1 ! Copyright (C) 2007, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays byte-arrays generic assocs hashtables io.binary
4 kernel kernel.private math namespaces sequences words
5 quotations strings alien.accessors alien.strings layouts system
6 combinators math.bitfields words.private cpu.architecture
7 math.order accessors growable ;
8 IN: generator.fixup
9
10 : no-stack-frame -1 ; inline
11
12 TUPLE: frame-required n ;
13
14 : frame-required ( n -- ) \ frame-required boa , ;
15
16 : stack-frame-size ( code -- n )
17     no-stack-frame [
18         dup frame-required? [ frame-required-n max ] [ drop ] if
19     ] reduce ;
20
21 GENERIC: fixup* ( frame-size obj -- frame-size )
22
23 : code-format 22 getenv ;
24
25 : compiled-offset ( -- n ) building get length code-format * ;
26
27 TUPLE: label offset ;
28
29 : <label> ( -- label ) label new ;
30
31 M: label fixup*
32     compiled-offset swap set-label-offset ;
33
34 : define-label ( name -- ) <label> swap set ;
35
36 : resolve-label ( label/name -- ) dup label? [ get ] unless , ;
37
38 : if-stack-frame ( frame-size quot -- )
39     swap dup no-stack-frame =
40     [ 2drop ] [ stack-frame swap call ] if ; inline
41
42 M: word fixup*
43     {
44         { \ %prologue-later [ dup [ %prologue ] if-stack-frame ] }
45         { \ %epilogue-later [ dup [ %epilogue ] if-stack-frame ] }
46     } case ;
47
48 SYMBOL: relocation-table
49 SYMBOL: label-table
50
51 ! Relocation classes
52 : rc-absolute-cell     0 ;
53 : rc-absolute          1 ;
54 : rc-relative          2 ;
55 : rc-absolute-ppc-2/2  3 ;
56 : rc-relative-ppc-2    4 ;
57 : rc-relative-ppc-3    5 ;
58 : rc-relative-arm-3    6 ;
59 : rc-indirect-arm      7 ;
60 : rc-indirect-arm-pc   8 ;
61
62 : rc-absolute? ( n -- ? )
63     dup rc-absolute-cell =
64     over rc-absolute =
65     rot rc-absolute-ppc-2/2 = or or ;
66
67 ! Relocation types
68 : rt-primitive 0 ;
69 : rt-dlsym     1 ;
70 : rt-literal   2 ;
71 : rt-dispatch  3 ;
72 : rt-xt        4 ;
73 : rt-here      5 ;
74 : rt-label     6 ;
75
76 TUPLE: label-fixup label class ;
77
78 : label-fixup ( label class -- ) \ label-fixup boa , ;
79
80 M: label-fixup fixup*
81     dup class>> rc-absolute?
82     [ "Absolute labels not supported" throw ] when
83     dup label>> swap class>> compiled-offset 4 - rot
84     3array label-table get push ;
85
86 TUPLE: rel-fixup arg class type ;
87
88 : rel-fixup ( arg class type -- ) \ rel-fixup boa , ;
89
90 : push-4 ( value vector -- )
91     [ length ] [ B{ 0 0 0 0 } swap push-all ] [ underlying>> ] tri
92     swap set-alien-unsigned-4 ;
93
94 M: rel-fixup fixup*
95     [ [ arg>> ] [ class>> ] [ type>> ] tri { 0 8 16 } bitfield ]
96     [ class>> rc-absolute-cell = cell 4 ? compiled-offset swap - ] bi
97     [ relocation-table get push-4 ] bi@ ;
98
99 M: frame-required fixup* drop ;
100
101 M: integer fixup* , ;
102
103 : adjoin* ( obj table -- n )
104     2dup swap [ eq? ] curry find drop
105     [ 2nip ] [ dup length >r push r> ] if* ;
106
107 SYMBOL: literal-table
108
109 : add-literal ( obj -- n ) literal-table get adjoin* ;
110
111 : add-dlsym-literals ( symbol dll -- )
112     >r string>symbol r> 2array literal-table get push-all ;
113
114 : rel-dlsym ( name dll class -- )
115     >r literal-table get length >r
116     add-dlsym-literals
117     r> r> rt-dlsym rel-fixup ;
118
119 : rel-word ( word class -- )
120     >r add-literal r> rt-xt rel-fixup ;
121
122 : rel-primitive ( word class -- )
123     >r def>> first r> rt-primitive rel-fixup ;
124
125 : rel-literal ( literal class -- )
126     >r add-literal r> rt-literal rel-fixup ;
127
128 : rel-this ( class -- )
129     0 swap rt-label rel-fixup ;
130
131 : rel-here ( class -- )
132     0 swap rt-here rel-fixup ;
133
134 : init-fixup ( -- )
135     BV{ } clone relocation-table set
136     V{ } clone label-table set ;
137
138 : resolve-labels ( labels -- labels' )
139     [
140         first3 label-offset
141         [ "Unresolved label" throw ] unless*
142         3array
143     ] map concat ;
144
145 : fixup ( code -- literals relocation labels code )
146     [
147         init-fixup
148         dup stack-frame-size swap [ fixup* ] each drop
149
150         literal-table get >array
151         relocation-table get >byte-array
152         label-table get resolve-labels
153     ] { } make ;