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.bitwise words.private cpu.architecture
7 math.order accessors growable ;
8 IN: compiler.generator.fixup
10 : no-stack-frame -1 ; inline
12 TUPLE: frame-required n ;
14 : frame-required ( n -- ) \ frame-required boa , ;
16 : stack-frame-size ( code -- n )
18 dup frame-required? [ n>> max ] [ drop ] if
21 GENERIC: fixup* ( frame-size obj -- frame-size )
23 : code-format 22 getenv ;
25 : compiled-offset ( -- n ) building get length code-format * ;
29 : <label> ( -- label ) label new ;
32 compiled-offset >>offset drop ;
34 : define-label ( name -- ) <label> swap set ;
36 : resolve-label ( label/name -- ) dup label? [ get ] unless , ;
38 : if-stack-frame ( frame-size quot -- )
39 swap dup no-stack-frame =
40 [ 2drop ] [ stack-frame swap call ] if ; inline
44 { \ %prologue-later [ dup [ %prologue ] if-stack-frame ] }
45 { \ %epilogue-later [ dup [ %epilogue ] if-stack-frame ] }
48 SYMBOL: relocation-table
52 : rc-absolute-cell 0 ;
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 ;
60 : rc-indirect-arm-pc 8 ;
62 : rc-absolute? ( n -- ? )
63 dup rc-absolute-cell =
65 rot rc-absolute-ppc-2/2 = or or ;
77 TUPLE: label-fixup label class ;
79 : label-fixup ( label class -- ) \ label-fixup boa , ;
82 dup class>> rc-absolute?
83 [ "Absolute labels not supported" throw ] when
84 dup label>> swap class>> compiled-offset 4 - rot
85 3array label-table get push ;
87 TUPLE: rel-fixup arg class type ;
89 : rel-fixup ( arg class type -- ) \ rel-fixup boa , ;
91 : push-4 ( value vector -- )
92 [ length ] [ B{ 0 0 0 0 } swap push-all ] [ underlying>> ] tri
93 swap set-alien-unsigned-4 ;
96 [ [ arg>> ] [ class>> ] [ type>> ] tri { 0 8 16 } bitfield ]
97 [ class>> rc-absolute-cell = cell 4 ? compiled-offset swap - ] bi
98 [ relocation-table get push-4 ] bi@ ;
100 M: frame-required fixup* drop ;
102 M: integer fixup* , ;
104 : adjoin* ( obj table -- n )
105 2dup swap [ eq? ] curry find drop
106 [ 2nip ] [ dup length >r push r> ] if* ;
108 SYMBOL: literal-table
110 : add-literal ( obj -- n ) literal-table get adjoin* ;
112 : add-dlsym-literals ( symbol dll -- )
113 >r string>symbol r> 2array literal-table get push-all ;
115 : rel-dlsym ( name dll class -- )
116 >r literal-table get length >r
118 r> r> rt-dlsym rel-fixup ;
120 : rel-word ( word class -- )
121 >r add-literal r> rt-xt rel-fixup ;
123 : rel-primitive ( word class -- )
124 >r def>> first r> rt-primitive rel-fixup ;
126 : rel-literal ( literal class -- )
127 >r add-literal r> rt-literal rel-fixup ;
129 : rel-this ( class -- )
130 0 swap rt-label rel-fixup ;
132 : rel-here ( class -- )
133 0 swap rt-here rel-fixup ;
136 BV{ } clone relocation-table set
137 V{ } clone label-table set ;
139 : resolve-labels ( labels -- labels' )
142 [ "Unresolved label" throw ] unless*
146 : fixup ( code -- literals relocation labels code )
149 dup stack-frame-size swap [ fixup* ] each drop
151 literal-table get >array
152 relocation-table get >byte-array
153 label-table get resolve-labels