1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: out 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary: out
15 *
16 ******************************************************************************/
17
18 #include "../genteeapi/gentee.h"
19 #include "../vm/vmload.h"
20 #include "lexem.h"
21
22 /*-----------------------------------------------------------------------------
23 *
24 * ID: out_addubyte 22.11.06 0.0.A.
25 *
26 * Summary: Append a byte
27 *
28 -----------------------------------------------------------------------------*/
29
30 void STDCALL out_addubyte( uint val )
31 {
32 buf_appendch( _compile->pout, ( ubyte )val );
33 }
34
35 /*-----------------------------------------------------------------------------
36 *
37 * ID: out_adduint 22.11.06 0.0.A.
38 *
39 * Summary: Append a unsigned int
40 *
41 -----------------------------------------------------------------------------*/
42
43 uint STDCALL out_adduint( uint val )
44 {
45 buf_appenduint( _compile->pout, val );
46 return _compile->pout->use - sizeof( uint );
47 }
48
49 /*-----------------------------------------------------------------------------
50 *
51 * ID: out_addlong 22.11.06 0.0.A.
52 *
53 * Summary: Append a long
54 *
55 -----------------------------------------------------------------------------*/
56
57 void STDCALL out_addulong( ulong64 val )
58 {
59 buf_appendulong( _compile->pout, val );
60 }
61
62 /*-----------------------------------------------------------------------------
63 *
64 * ID: out_add2ui 22.11.06 0.0.A.
65 *
66 * Summary: Append two unsigned ints
67 *
68 -----------------------------------------------------------------------------*/
69
70 void STDCALL out_add2uint( uint val1, uint val2 )
71 {
72 out_adduint( val1 );
73 out_adduint( val2 );
74 }
75
76 /*-----------------------------------------------------------------------------
77 *
78 * ID: out_addptr 22.11.06 0.0.A.
79 *
80 * Summary: Append data with alignment.
81 *
82 -----------------------------------------------------------------------------*/
83
84 void STDCALL out_addptr( pubyte data, uint size )
85 {
86 uint val;
87
88 //Выравнивание до dword
89 buf_append( _compile->pout, data, size );
90 buf_append( _compile->pout, ( pubyte )&val,
91 ( sizeof( uint ) - size & ( sizeof( uint ) - 1 ) ) & 3 );
92 }
93
94 /*-----------------------------------------------------------------------------
95 *
96 * ID: out_addbuf 22.11.06 0.0.A.
97 *
98 * Summary: Append buf with alignment.
99 *
100 -----------------------------------------------------------------------------*/
101
102 void STDCALL out_addbuf( pbuf data )
103 {
104 buf_add( _compile->pout, data );
105 }
106
107 /*-----------------------------------------------------------------------------
108 *
109 * ID: out_addname 22.11.06 0.0.A.
110 *
111 * Summary: Append name.
112 *
113 -----------------------------------------------------------------------------*/
114
115 void STDCALL out_addname( pubyte data )
116 {
117 buf_append( _compile->pout, data, mem_len( data ) + 1 );
118 }
119
120 /*-----------------------------------------------------------------------------
121 *
122 * ID: out_adduints 22.11.06 0.0.A.
123 *
124 * Summary: Append unsigned ints
125 *
126 -----------------------------------------------------------------------------*/
127
128 void CDECLCALL out_adduints( uint count, ... )
129 {
130 puint data;
131 va_list args;
132 uint i;
133
134 va_start( args, count );
135 buf_expand( _compile->pout, sizeof( uint ) * count );
136 data = ( puint )( _compile->pout->data + _compile->pout->use );
137 for ( i = 0; i < count; i++ )
138 {
139 *( data++ ) = ( uint )va_arg( args, uint );
140 }
141 _compile->pout->use += sizeof( uint ) * count;
142 va_end( args );
143 }
144
145 /*-----------------------------------------------------------------------------
146 *
147 * ID: out_head 22.11.06 0.0.A.
148 *
149 * Summary: Initializing out buffer
150 *
151 -----------------------------------------------------------------------------*/
152
153 void STDCALL out_head( uint type, uint flag, pubyte name )
154 {
155 out_addubyte( type );
156
157 if ( name )
158 flag |= GHCOM_NAME;
159
160 out_add2uint( flag, 0 );
161 if ( name )
162 {
163 if ( type == OVM_BYTECODE || type == OVM_EXFUNC )
164 {
165 if ( flag & GHBC_METHOD || flag & GHBC_PROPERTY )
166 out_addubyte( '@' );
167 if ( flag & GHBC_OPERATOR )
168 out_addubyte( '#' );
169 }
170 out_addname( name );
171 }
172 }
173
174 /*-----------------------------------------------------------------------------
175 *
176 * ID: out_init 22.11.06 0.0.A.
177 *
178 * Summary: Initializing out buffer
179 *
180 -----------------------------------------------------------------------------*/
181
182 void STDCALL out_init( uint type, uint flag, pubyte name )
183 {
184 _compile->pout = &_compile->out;
185
186 // Уменьшаем если слишком большой размер
187 if ( buf_len( _compile->pout ) > 0x100000 )
188 buf_alloc( _compile->pout, 0x20000 );
189
190 buf_clear( _compile->pout );
191 out_head( type, flag, name );
192 }
193
194 /*-----------------------------------------------------------------------------
195 *
196 * ID: out_finish 22.11.06 0.0.A.
197 *
198 * Summary: Finish out buffer
199 *
200 -----------------------------------------------------------------------------*/
201
202 pubyte STDCALL out_finish( void )
203 {
204 uint len = buf_len( _compile->pout );
205
206 *( puint )( buf_ptr( _compile->pout ) + sizeof( uint ) + 1 ) = len;
207 // print("Len=%i\n", len );
208 return buf_ptr( _compile->pout );
209 }
210
211 /*-----------------------------------------------------------------------------
212 *
213 * ID: out_setuint 22.11.06 0.0.A.
214 *
215 * Summary: Change a unsigned int
216 *
217 -----------------------------------------------------------------------------*/
218
219 void STDCALL out_setuint( uint off, uint val )
220 {
221 *( puint )( buf_ptr( _compile->pout ) + off ) = val;
222 }
223
224 /*-----------------------------------------------------------------------------
225 *
226 * ID: out_addvar 22.11.06 0.0.A.
227 *
228 * Summary: Append VARMODE
229 *
230 -----------------------------------------------------------------------------*/
231
232 void STDCALL out_addvar( ps_descid field, uint flag, pubyte data )
233 {
234 povmtype ptype;
235 uint i, size = 0;
236
237 out_adduint( field->idtype );
238 out_addubyte( flag );
239 if ( flag & VAR_NAME )
240 out_addname( field->name );
241
242 if ( flag & VAR_OFTYPE )
243 {
244 out_adduint( field->oftype );
245 }
246 if ( flag & VAR_DIM )
247 {
248 out_addubyte( field->msr );
249 for ( i = 0; i < field->msr; i++ )
250 out_adduint( field->msrs[ i ] );
251 }
252
253 if ( flag & VAR_DATA )
254 {
255 ptype = ( povmtype )PCMD( field->idtype );
256 if ( ptype->vmo.flag & GHTY_STACK )
257 buf_append( _compile->pout, data, ptype->size );
258 else
259 {
260 size = flag & VAR_IDNAME ? mem_len( data ) + 1 : buf_len( ( pbuf )data );
261 if ( ptype->vmo.id != TStr )
262 out_adduint( size );
263
264 if ( flag & VAR_IDNAME )
265 buf_append( _compile->pout, data, size );
266 else
267 buf_add( _compile->pout, ( pbuf )data );
268 }
269 // print(" %i size = %x\n", flag, size );
270 }
271 // print("name=%s type=%i flag=%x\n", name, type, flag );
272 }
273
274 /*-----------------------------------------------------------------------------
275 *
276 * ID: out_addvar 17.01.08 0.0.A.
277 *
278 * Summary: Append Debug Trace
279 *
280 -----------------------------------------------------------------------------*/
281 void STDCALL out_debugtrace( plexem curlex )
282 {
283 if ( _compile->flag & CMPL_DEBUG )
284 {
285 out_adduints( 3,
286 CDwload,
287 str_pos2line( _compile->cur->src, curlex->pos, 0 ) + 1,
288 CDbgTrace );
289 }
290 }