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: ge 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary:
15 *
16 ******************************************************************************/
17
18 #ifndef RUNTIME
19
20 #include "ge.h"
21 #include "../vm/vm.h"
22 #include "../vm/vmload.h"
23 #include "../bytecode/bytecode.h"
24 #include "../genteeapi/gentee.h"
25
26 puint optiused;
27
28 void STDCALL geopti_var( pvartype var )
29 {
30 ge_getused( var->type );
31
32 if ( var->flag & VAR_OFTYPE )
33 ge_getused( var->oftype );
34 }
35
36 void STDCALL geopti_varlist( pvartype pvar, uint count )
37 {
38 uint i;
39
40 for ( i = 0; i < count; i++ )
41 geopti_var( pvar++ );
42 }
43
44 void STDCALL ge_getused( uint id )
45 {
46 puint ptr, end;
47 povmbcode bcode;
48 povmtype ptype;
49 pvmobj pvmo;
50 uint cmd, i, k, count = 0;
51
52 if ( id < KERNEL_COUNT || optiused[ id ] )
53 return;
54 optiused[ id ] = 1;
55 pvmo = ( pvmobj )PCMD( id );
56
57 if ( pvmo->type == OVM_BYTECODE )
58 {
59 bcode = ( povmbcode )pvmo;
60 geopti_var( bcode->vmf.ret );
61 geopti_varlist( bcode->vmf.params, bcode->vmf.parcount );
62
63 for ( i = 0; i < bcode->setcount; i++ )
64 count += bcode->sets[i].count;
65 geopti_varlist( bcode->vars, count );
66
67 ptr = ( puint )bcode->vmf.func;
68 if ( !ptr )
69 return;
70
71 end = ( puint )( ( pubyte )ptr + bcode->bcsize );
72 while ( ptr < end )
73 {
74 cmd = *ptr++;
75 if ( cmd < CNop || cmd >= CNop + STACK_COUNT )
76 {
77 if ( cmd >= KERNEL_COUNT )
78 ge_getused( cmd );
79 continue;
80 }
81
82 switch ( cmd )
83 {
84 case CQwload:
85 ptr += 2;
86 break;
87 case CDwload:
88 ptr++;
89 break;
90 case CDwsload:
91 i = *ptr++;
92 ptr += i;
93 break;
94 case CResload:
95 case CCmdload:
96 case CPtrglobal:
97 ge_getused( *ptr++ );
98 break;
99 case CDatasize:
100 i = *ptr++;
101 ptr += ( i >> 2 ) + ( i & 3 ? 1 : 0 );
102 break;
103 default:
104 switch ( shifts[ cmd - CNop ] )
105 {
106 case SH1_3:
107 case SH2_3:
108 ptr++;
109 case SHN1_2:
110 case SH0_2:
111 case SH1_2:
112 ptr++;
113 break;
114 }
115 }
116 }
117 }
118 if ( pvmo->type == OVM_EXFUNC )
119 {
120 geopti_var( (( povmfunc )pvmo)->vmf.ret );
121 geopti_varlist( (( povmfunc )pvmo)->vmf.params,
122 (( povmfunc )pvmo)->vmf.parcount );
123
124 if ( pvmo->flag & GHEX_IMPORT )
125 ge_getused( (( povmfunc )pvmo)->import );
126 }
127 if ( pvmo->type == OVM_TYPE )
128 {
129 ptype = ( povmtype )pvmo;
130
131 if ( pvmo->flag & GHTY_INHERIT )
132 ge_getused( ptype->inherit );
133
134 if ( pvmo->flag & GHTY_INDEX )
135 {
136 ge_getused( ptype->index.type );
137 ge_getused( ptype->index.oftype );
138 }
139 if ( pvmo->flag & GHTY_INITDEL )
140 {
141 ge_getused( ptype->ftype[ FTYPE_INIT ] );
142 ge_getused( ptype->ftype[ FTYPE_DELETE ] );
143 }
144 if ( pvmo->flag & GHTY_EXTFUNC )
145 {
146 ge_getused( ptype->ftype[ FTYPE_OFTYPE ] );
147 ge_getused( ptype->ftype[ FTYPE_COLLECTION ] );
148 }
149 if ( pvmo->flag & GHTY_ARRAY )
150 {
151 i = 0;
152 while ( ptype->ftype[ FTYPE_ARRAY + i ] )
153 i++;
154 ge_getused( i == 1 ? ptype->ftype[ FTYPE_ARRAY ] : i );
155 if ( i > 1 )
156 for ( k = 0; k < i; k++ )
157 ge_getused( ptype->ftype[ FTYPE_ARRAY + k ] );
158 }
159 geopti_varlist( ptype->children, ptype->count );
160 }
161 if ( pvmo->type == OVM_GLOBAL )
162 geopti_var( (( povmglobal )pvmo)->type );
163 }
164
165 void STDCALL ge_optimize( void )
166 {
167 uint i, count, main = 0;
168 pvmobj pvmo;
169 pubyte cur;
170
171 count = arr_count( &_vm.objtbl );
172 // Deletes ALIAS and DEFINE
173 for ( i = KERNEL_COUNT; i < count ; i++ )
174 {
175 pvmo = ( pvmobj )PCMD( i );
176 if ( pvmo->flag & GHRT_SKIP )
177 continue;
178 switch ( pvmo->type )
179 {
180 case OVM_DEFINE:
181 if ( _compile->popti->flag & OPTI_DEFINE )
182 pvmo->flag |= GHRT_SKIP;
183 break;
184 case OVM_ALIAS:
185 pvmo->flag |= GHRT_SKIP;
186 break;
187 }
188 }
189 if ( !( _compile->popti->flag & OPTI_AVOID ))
190 return;
191 optiused = mem_allocz( count * sizeof( uint ));
192 for ( i = KERNEL_COUNT; i < count; i++ )
193 {
194 pvmo = ( pvmobj )PCMD( i );
195
196 if ( pvmo->name )
197 {
198 cur = _compile->popti->avoidon;
199 while ( *cur )
200 {
201 if ( ptr_wildcardignore( pvmo->name, cur ))
202 {
203 ge_getused( i );
204 break;
205 }
206 cur += mem_len( cur ) + 1;
207 }
208 }
209
210 if ( pvmo->type == OVM_BYTECODE || pvmo->type == OVM_EXFUNC )
211 if ( pvmo->flag & GHBC_ENTRY )
212 ge_getused( i );
213 else
214 if ( pvmo->flag & GHBC_MAIN )
215 if ( _compile->popti->flag & OPTI_MAIN )
216 main = i;
217 else
218 ge_getused( i );
219 }
220 if ( main )
221 ge_getused( main );
222
223 for ( i = KERNEL_COUNT; i < count ; i++ )
224 {
225 pvmo = ( pvmobj )PCMD( i );
226 if ( !optiused[ i ] )
227 pvmo->flag |= GHRT_SKIP;
228 }
229
230 mem_free( optiused );
231 }
232
233 #endif
Edit