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: vmtype 26.12.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary:
15 *
16 ******************************************************************************/
17
18 #include "vmrun.h"
19 #include "vmtype.h"
20 #include "vmload.h"
21 #include "../common/collection.h"
22 //#include "../bytecode/bytecode.h"
23
24 /*-----------------------------------------------------------------------------
25 *
26 * ID: type_vardelete 26.12.06 0.0.A.
27 *
28 * Summary: Delete variables
29 *
30 -----------------------------------------------------------------------------*/
31
32 void STDCALL type_vardelete( pubyte start, pvartype psub, uint count,
33 uint align )
34 {
35 povmtype ptype;
36 pubyte pvar;
37
38 while ( count-- )
39 {
40 ptype = ( povmtype )PCMD( psub->type );
41 if ( !( ptype->vmo.flag & GHTY_STACK ))
42 {
43 pvar = start + ( psub->off << ( align ? 2 : 0 ));
44 // print("Var delete = %x type=%i RTDEL=%x\n", pvar, psub->type,
45 // ptype->vmo.flag & GHRT_DELETE);
46 if ( ptype->ftype[ FTYPE_DELETE ] )
47 vm_runone( ptype->ftype[ FTYPE_DELETE ], ( uint )pvar );
48
49 if ( ptype->vmo.flag & GHRT_DELETE )
50 type_vardelete( pvar, ptype->children, ptype->count, 0 );
51 }
52 psub++;
53 }
54 }
55
56 /*-----------------------------------------------------------------------------
57 *
58 * ID: type_varinit 26.12.06 0.0.A.
59 *
60 * Summary: Init variables
61 *
62 -----------------------------------------------------------------------------*/
63
64 void STDCALL type_varinit( pubyte start, pvartype psub, uint count,
65 uint align )
66 {
67 povmtype ptype;
68 pubyte pvar;
69 uint ret;
70 pcollect pcol;
71
72 while ( count-- )
73 {
74 ptype = ( povmtype )PCMD( psub->type );
75 pvar = start + ( psub->off << ( align ? 2 : 0 ));
76
77 if ( !( ptype->vmo.flag & GHTY_STACK ))
78 {
79 // print("Var init = %x type=%i align=%i\n", pvar, psub->type, align );
80 if ( ptype->vmo.flag & GHRT_INIT )
81 type_varinit( pvar, ptype->children, ptype->count, 0 );
82
83 if ( ptype->ftype[ FTYPE_INIT ] )
84 {
85 vm_runone( ptype->ftype[ FTYPE_INIT ], ( uint )pvar );
86 }
87 }
88 if ( psub->flag & VAR_OFTYPE && ptype->ftype[ FTYPE_OFTYPE ] )
89 {
90 vm_runtwo( ptype->ftype[ FTYPE_OFTYPE ], ( uint )pvar, psub->oftype );
91 }
92 if ( psub->flag & VAR_DIM && ptype->ftype[ FTYPE_ARRAY + psub->dim - 1 ] )
93 {
94 uint params[ MAX_MSR + 1 ];
95 uint i;
96
97 params[ 0 ] = ( uint )pvar;
98 for ( i = 0; i < psub->dim; i++ )
99 params[ i + 1 ] = psub->ptr[i];
100 vm_run( ptype->ftype[ FTYPE_ARRAY + psub->dim - 1 ], ( puint )¶ms, &ret, 8192 );
101 }
102 if ( psub->flag & VAR_DATA )
103 {
104 pubyte pdata = ( pubyte )( psub->ptr + psub->dim );
105 if ( ptype->vmo.flag & GHTY_STACK )
106 mem_copy( start, pdata, ptype->size );
107 else
108 switch ( ptype->vmo.id )
109 {
110 case TBuf:
111 buf_copy( ( pbuf )start, pdata + sizeof( uint ), *( puint )pdata );
112 break;
113 case TStr:
114 // str_copylen( ( pstr )start, pdata + sizeof( uint ), *( puint )pdata - 1 );
115 str_copyzero( ( pstr )start, pdata );
116 break;
117 case TCollection:
118 collect_copy( ( pcollect )start, pdata + sizeof( uint ));
119 break;
120 default:
121 if ( ptype->ftype[ FTYPE_COLLECTION ] )
122 {
123 // print("OK 0 %i %x%x%x%x%x%x%x%x%x\n", ptype->ftype[ FTYPE_COLLECTION ], pdata[0], pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], pdata[6], pdata[7], pdata[8], pdata[9]);
124 pcol = ( pcollect )type_new( TCollection, pdata );// + sizeof( uint ) );
125 vm_runtwo( ptype->ftype[ FTYPE_COLLECTION ], ( uint )start, ( uint )pcol );
126 type_destroy( pcol );
127 }
128 break;
129 }
130 }
131 psub++;
132 }
133 }
134
135 /*-----------------------------------------------------------------------------
136 *
137 * ID: type_setdelete 26.12.06 0.0.A.
138 *
139 * Summary: Delete local variables
140 *
141 -----------------------------------------------------------------------------*/
142
143 void STDCALL type_setdelete( pstackpos curpos, uint item )
144 {
145 povmbcode bcode;
146
147 // Has not been initialized
148 if ( !*( curpos->start + curpos->func->parsize + 1 + item ))
149 return;
150
151 bcode = BCODE( curpos );
152
153 type_vardelete( ( pubyte )*( curpos->start + curpos->func->parsize ),
154 bcode->vars + bcode->sets[ item ].first,
155 bcode->sets[ item ].count, 1 );
156 }
157
158 /*-----------------------------------------------------------------------------
159 *
160 * ID: type_setinit 26.12.06 0.0.A.
161 *
162 * Summary: Init local variables
163 *
164 -----------------------------------------------------------------------------*/
165
166 void STDCALL type_setinit( pstackpos curpos, uint item )
167 {
168 povmbcode bcode;
169 pubyte ptr;
170
171 type_setdelete( curpos, item );
172
173 bcode = BCODE( curpos );
174
175 ptr = ( pubyte )*( curpos->start + curpos->func->parsize );
176 mem_zeroui( ( puint )ptr + bcode->sets[ item ].off, bcode->sets[ item ].size );
177 type_varinit( ptr, bcode->vars + bcode->sets[ item ].first,
178 bcode->sets[ item ].count, 1 );
179 // Отмечаем что было инициализация множества
180 *( curpos->start + curpos->func->parsize + 1 + item ) = 1;
181 }
182
183 /*-----------------------------------------------------------------------------
184 *
185 * ID: type_init 26.12.06 0.0.A.
186 *
187 * Summary: Initialize OVM_TYPE Set GHRT_INIT & GHRT_DEINIT
188 *
189 -----------------------------------------------------------------------------*/
190
191 void STDCALL type_initialize( uint idtype )
192 {
193 uint i, isinit = 0, isdelete = 0;
194 povmtype ptype = ( povmtype )PCMD( idtype );
195 povmtype psub;
196
197 for ( i = 0; i < ptype->count; i++ )
198 {
199 psub = ( povmtype )PCMD( ptype->children[ i ].type );
200 if ( !psub->vmo.flag & GHRT_LOADED )
201 type_initialize( psub->vmo.id );
202
203 if ( psub->vmo.flag & GHRT_INIT )
204 isinit = 1;
205
206 if ( psub->vmo.flag & GHRT_DELETE )
207 isdelete = 1;
208
209 psub++;
210 }
211 ptype->vmo.flag |= GHRT_LOADED;
212
213 if ( ptype->ftype[ FTYPE_INIT ] )
214 isinit = 1;
215 if ( ptype->ftype[ FTYPE_DELETE ] )
216 isdelete = 1;
217
218 if ( isinit )
219 ptype->vmo.flag |= GHRT_INIT;
220
221 if ( isdelete )
222 ptype->vmo.flag |= GHRT_DELETE;
223 // print("Type=%i name=%s INIT=%x DELETE=%x\n", idtype, ptype->vmo.name, ptype->vmo.flag & GHRT_INIT,
224 // ptype->vmo.flag & GHRT_DELETE );
225 }
226
227 /*-----------------------------------------------------------------------------
228 *
229 * ID: type_isinherit 26.12.06 0.0.A.
230 *
231 * Summary:
232 *
233 -----------------------------------------------------------------------------*/
234
235 uint STDCALL type_isinherit( uint idtype, uint idowner )
236 {
237 povmtype curtype;
238
239 if ( idtype == idowner )
240 return 1;
241 if ( !idtype )
242 return 0;
243 curtype = ( povmtype )PCMD( idtype );
244 while ( curtype->inherit )
245 {
246 if ( idowner == curtype->inherit )
247 return 1;
248 curtype = ( povmtype )PCMD( curtype->inherit );
249 }
250 return 0;
251 }
252
253 /*-----------------------------------------------------------------------------
254 * Id: type_hasinit F
255 *
256 * Summary: Whether an object should be initialized. Specifies the necessity
257 to call the function #a(type_init) for initiating an object of
258 this type.
259 *
260 * Params: idtype - The type of an object.
261 *
262 * Return: #b(1) is returned if it is necessary to call #a(type_init), #b(0) is
263 returned otherwise.
264 *
265 * Define: func uint type_hasinit( uint idtype )
266 *
267 -----------------------------------------------------------------------------*/
268
269 uint STDCALL type_hasinit( uint idtype )
270 {
271 return (( pvmobj )PCMD( idtype ))->flag & GHRT_INIT ? 1 : 0;
272 }
273
274 /*-----------------------------------------------------------------------------
275 * Id: type_hasdelete F
276 *
277 * Summary: Whether an object should be deleted. Specifies the necessity to
278 call the function #a(type_delete) for deleting an object of
279 this type.
280 *
281 * Params: idtype - The type of an object.
282 *
283 * Return: #b(1) is returned if it is necessary to call #a(type_delete),
284 #b(0) is returned otherwise.
285 *
286 * Define: func uint type_hasdelete( uint idtype )
287 *
288 -----------------------------------------------------------------------------*/
289
290 uint STDCALL type_hasdelete( uint idtype )
291 {
292 return (( pvmobj )PCMD( idtype ))->flag & GHRT_DELETE ? 1 : 0;
293 }
294
295 /*-----------------------------------------------------------------------------
296 * Id: type_init F
297 *
298 * Summary: Initiate the object as located by the pointer. Gentee initializes
299 objects automaticaly. Use this function only if you allocated the
300 memory for the variable.
301 *
302 * Params: ptr - The pointer to the memory space where the object being /
303 created is located.
304 idtype - The type of the object.
305 *
306 * Return: The pointer to the object is returned.
307 *
308 * Define: func uint type_init( pubyte ptr, uint idtype )
309 *
310 -----------------------------------------------------------------------------*/
311
312 pubyte STDCALL type_init( pubyte ptr, uint idtype )
313 {
314 povmtype ptype = ( povmtype )PCMD( idtype );
315 vartype vtype;
316
317 if ( ptype->vmo.flag & GHTY_STACK )
318 {
319 *( puint )ptr = 0;
320 if ( ptype->stsize > 1 )
321 *(( puint )ptr + 1 ) = 0;
322 }
323 else
324 {
325 mem_zero( ptr, ptype->size );
326
327 vtype.type = idtype;
328 vtype.off = 0;
329 vtype.flag = 0;
330 // vtype.oftype = 0;
331 // vtype.dim = 0;
332 // vtype.data = 0;
333
334 type_varinit( ptr, &vtype, 1, 0 );
335 }
336 return ptr;
337 }
338
339 /*-----------------------------------------------------------------------------
340 * Id: type_delete F
341 *
342 * Summary: Delete the object as located by the pointer. Gentee deletes
343 objects automaticaly. Use this function only if you allocated the
344 memory for the variable.
345 *
346 * Params: ptr - The pointer to the memory space where the object being /
347 deleted is located.
348 idtype - The type of the object.
349 *
350 * Define: func type_delete( pubyte ptr, uint idtype )
351 *
352 -----------------------------------------------------------------------------*/
353
354 void STDCALL type_delete( pubyte ptr, uint idtype )
355 {
356 povmtype ptype = ( povmtype )PCMD( idtype );
357 vartype vtype;
358
359 if ( !( ptype->vmo.flag & GHTY_STACK ))
360 {
361 vtype.type = idtype;
362 vtype.off = 0;
363 vtype.oftype = 0;
364 vtype.dim = 0;
365 vtype.data = 0;
366
367 type_vardelete( ptr, &vtype, 1, 0 );
368 }
369 }
370
371 /*-----------------------------------------------------------------------------
372 * Id: sizeof F
373 *
374 * Summary: Get the size of the type.
375 *
376 * Params: idtype - Identifier or the name of the type. The compiler changes /
377 the name of the type to its identifier.
378 *
379 * Return: The type size in bytes.
380 *
381 * Define: func uint sizeof( uint idtype )
382 *
383 -----------------------------------------------------------------------------*/
384
385 uint STDCALL type_sizeof( uint idtype )
386 {
387 return (( povmtype )PCMD( idtype ))->size;
388 }
389
390 /*-----------------------------------------------------------------------------
391 *
392 * ID: type_compfull 26.12.06 0.0.A.
393 *
394 * Summary: Сплошная совместимость целочисленных тип
395 *
396 -----------------------------------------------------------------------------*/
397
398 uint STDCALL type_compfull( uint idtype )
399 {
400 if ( idtype >= TInt && idtype <= TUshort )
401 return TUint;
402 if ( idtype == TLong || idtype == TUlong )
403 return TUlong;
404 return idtype;
405 }
406
407 /*-----------------------------------------------------------------------------
408 *
409 * ID: type_new 26.12.06 0.0.A.
410 *
411 * Summary: Create an object
412 *
413 -----------------------------------------------------------------------------*/
414
415 pvoid STDCALL type_new( uint idtype, pubyte data )
416 {
417 vartype vtype;
418 povmtype ptype = ( povmtype )PCMD( idtype );
419 pvoid ret;
420
421 ret = mem_allocz( max( sizeof( uint ), ptype->size ) + sizeof( uint ));
422 // Перед объектом идет его тип
423 *( puint )ret = idtype;
424 ret = ( pubyte )ret + sizeof( uint );
425 mem_zero( &vtype, sizeof( vartype ));
426 vtype.flag = data ? VAR_DATA : 0;
427 vtype.type = idtype;
428 vtype.ptr = ( puint )data;
429
430 type_varinit( ret, &vtype, 1, 1 );
431
432 return ret;
433 }
434
435 /*-----------------------------------------------------------------------------
436 ** Id: destroy F
437 *
438 * Summary: Destroying an object. Destroying an object created by the function
439 #a(new).
440 *
441 * Params: obj - The pointer to the object to be destroyed.
442 *
443 * Define: func destroy( uint obj )
444 *
445 -----------------------------------------------------------------------------*/
446
447 void STDCALL type_destroy( pvoid obj )
448 {
449 vartype vtype;
450
451 mem_zero( &vtype, sizeof( vartype ));
452 // vtype.flag = 0;
453 vtype.type = *(( puint )obj - 1 );
454 type_vardelete( obj, &vtype, 1, 1 );
455 mem_free( ( puint )obj - 1 );
456 }
457
458 // 1 добавляется для того чтобы если один из двух операндов знаковый
459 // то использовалась знаковая опреация
460 const ubyte compnum[ 10 ][ 10 ] =
461 {
462 // Int UInt Byte UByte Short UShort Float Double Long ULong
463 /* Int */ 100, 91, 60, 51, 80, 71, 0, 0, 0, 0,
464 /* UInt */ 90, 100, 50, 60, 70, 80, 0, 0, 0, 0,
465 /* Byte */ 80, 51, 100, 71, 90, 61, 0, 0, 0, 0,
466 /* UByte */ 50, 80, 70, 100, 60, 90, 0, 0, 0, 0,
467 /* Short */ 90, 61, 80, 51, 100, 71, 0, 0, 0, 0,
468 /* UShort */ 60, 90, 50, 80, 70, 100, 0, 0, 0, 0,
469 /* Float */ 0, 0, 0, 0, 0, 0, 100, 0, 0, 0,
470 /* Double */ 0, 0, 0, 0, 0, 0, 0, 100, 0, 0,
471 /* Long */ 0, 0, 0, 0, 0, 0, 0, 0, 100, 81,
472 /* ULong */ 0, 0, 0, 0, 0, 0, 0, 0, 80, 100,
473 ///* Any */ 100, 100, 100, 100, 100, 100, 100, 0, 0, 0, 100,
474 };
475
476 /*-----------------------------------------------------------------------------
477 *
478 * ID: type_compat 26.12.06 0.0.A.
479 *
480 * Summary: Compatibility of types
481 *
482 -----------------------------------------------------------------------------*/
483
484 uint STDCALL type_compat( uint idleft, uint idright, uint oftype )
485 {
486 uint i;
487
488 if ( idleft == idright || idleft == TAny || idright == TAny )
489 return 100;
490
491 if ( idleft <= TUlong && idright <= TUlong )
492 {
493 i = compnum[ idright - TInt ][ idleft - TInt ];
494 if ( oftype && (( povmtype )PCMD( idleft ))->size !=
495 (( povmtype )PCMD( idright ))->size )
496 i = 0;
497 return i;
498 }
499 return type_isinherit( idleft, idright ) ? 45 : 0;
500 }
501