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: vmload 28.12.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary:
15 *
16 ******************************************************************************/
17
18 #include "vmload.h"
19 #include "vmmanage.h"
20 #include "../compiler/operlist.h"
21 #include "../bytecode/cmdlist.h"
22 #include "../bytecode/bytecode.h"
23
24 #include "../genteeapi/gentee.h"
25 #include "../compiler/lexem.h"
26 #include "../compiler/macro.h"
27
28 /*-----------------------------------------------------------------------------
29 *
30 * ID: load_bwd 26.12.06 0.0.A.
31 *
32 * Summary: Unpacking bwd number.
33 * byte < 188 returns byte
34 * byte from 188 to 253 returns 256 * ( byte - 188 ) + [ byte + 1 ]
35 * byte == 254 returns next ushort
36 * byte == 255 returns next uint
37 *
38 -----------------------------------------------------------------------------*/
39
40 uint STDCALL load_bwd( pubyte * ptr )
41 {
42 uint ret;
43 pubyte cur = *ptr;
44
45 if ( _vm.ipack )
46 {
47 ret = *cur++;
48 if ( ret > 187 )
49 if ( ret == MAX_BYTE - 1 )
50 {
51 ret = *( pushort )cur;
52 cur += 2; // пропускаем word
53 }
54 else
55 if ( ret == MAX_BYTE )
56 {
57 ret = *( puint )cur;
58 cur += 4; // пропускаем dword
59 }
60 else
61 ret = 0xFF * ( ret - 188 ) + *cur++;
62 }
63 else
64 {
65 ret = *( puint )cur;
66 cur += sizeof( uint );
67 }
68 *ptr = cur;
69 return ret;
70 }
71
72 /*-----------------------------------------------------------------------------
73 *
74 * ID: load_convert 26.12.06 0.0.A.
75 *
76 * Summary: Unpacking bwd number and convert.
77 *
78 -----------------------------------------------------------------------------*/
79
80 uint STDCALL load_convert( pubyte * ptr )
81 {
82 uint ret = load_bwd( ptr );
83
84 if ( ret >= KERNEL_COUNT )
85 ret += _vm.icnv;
86
87 return ret;
88 }
89
90 /*-----------------------------------------------------------------------------
91 *
92 * ID: load_addobj 19.10.06 0.0.A.
93 *
94 * Summary: Add an object to VM.
95 *
96 -----------------------------------------------------------------------------*/
97
98 pvmobj STDCALL load_addobj( uint over )
99 {
100 pvmobj obj, pover = NULL;
101 pvmfunc curobj = NULL;
102 uint idname = 0; // previous object
103 phashitem phi = NULL;
104 puint pidphi;
105
106 obj = ( pvmobj )_vm.pmng->top;
107 /* if ( flag & VMADD_CRC )
108 {
109 // CRC control
110 }*/
111 if ( obj->name && *obj->name )
112 { // Looking for an existing object with the same name
113 // and adding name if it is required
114 phi = hash_create( &_vm.objname, obj->name );
115 pidphi = ( puint )( phi + 1 );
116 // print("phi=%x link = %i %s mode = %i\n", phi, *pidphi, obj->name, _vm.loadmode );
117 if ( _vm.loadmode && ( idname = *pidphi)) // Object has already existed
118 {
119 uint curcount, objcount, i;
120
121 if ( !( obj->flag & GHRT_MAYCALL ))
122 goto error;
123
124 objcount = (( pvmfunc )obj)->parcount - ( obj->flag & GHBC_RESULT ? 1 : 0 );
125 while ( idname )
126 {
127 curobj = ( pvmfunc )PCMD( idname );
128 if ( !( curobj->vmo.flag & GHRT_MAYCALL ))
129 goto error;
130 // Compare parameters
131 curcount = curobj->parcount - ( curobj->vmo.flag & GHBC_RESULT ? 1 : 0 );
132
133 if ( curcount == objcount )
134 {
135 for ( i = 0; i < curcount; i++ )
136 {
137 if ( curobj->params[ i ].type !=
138 (( pvmfunc )obj )->params[ i ].type )
139 break;
140 }
141 if ( i == curcount ) // There is the same function
142 {
143 // Уходит впустую - реально не добавляем если у нас
144 // предварительное описание функции
145 if ( _vm.loadmode == VMLOAD_EXTERN )//|| _vm.loadmode == VMLOAD_FIRST )
146 return ( pvmobj )curobj;
147 // Байт код для данной функции уже есть - ошибка
148 if ( curobj->func )
149 goto error;
150 // idname == the found object
151 // over = idname;
152 break;
153 }
154 }
155 idname = curobj->vmo.nextname;
156 }
157 // if ( !idname )
158 // curobj = NULL;
159 }
160 }
161 // if ( over )
162 // idname = over;
163 // Object not found
164 if ( !idname && !over )
165 {
166 arr_appendnum( &_vm.objtbl, ( uint )obj );
167 obj->id = _vm.count++;
168 over = obj->id;
169 }
170 else
171 {
172 if ( !over )
173 over = idname;
174
175 pover = ( pvmobj )PCMD( over );
176 obj->id = over;
177 arr_setuint( &_vm.objtbl, over, ( uint )obj );
178 }
179 if ( phi )
180 {
181 // print("EQ0 phi=%x link = %i %s next=%i over=%i id = %i\n", phi, *pidphi, obj->name,
182 // obj->nextname, over, obj->id );
183 if ( pover && pover->nextname )
184 obj->nextname = pover->nextname;
185 else
186 if (( obj->id != *pidphi && obj->id < KERNEL_COUNT ) ||
187 obj->id > *pidphi )//( obj->id != *pidphi ) // fix: От зацикливания
188 {
189 obj->nextname = ( ushort )*pidphi;
190 *pidphi = obj->id;
191 }
192 // print("EQ1 phi=%x link = %i %s next=%i over=%i id = %i\n", phi, *pidphi, obj->name,
193 // obj->nextname, over, obj->id );
194 }
195
196 // Checking @init @delete @array @oftype =%{}
197 if ( obj->flag & GHRT_MAYCALL && obj->name )
198 {
199 uint ftype;
200 uint flag = 0;
201 // pubyte opname[32];
202
203 pvmfunc pfunc = ( pvmfunc )obj;
204
205 if ( obj->flag & GHBC_METHOD )
206 {
207 if ( pfunc->parcount == 1 && !mem_cmp( obj->name, "@init", 6 ))
208 {
209 flag = GHTY_INITDEL;
210 ftype = FTYPE_INIT;
211 }
212 if ( pfunc->parcount == 1 && !mem_cmp( obj->name, "@delete", 8 ))
213 {
214 flag = GHTY_INITDEL;
215 ftype = FTYPE_DELETE;
216 }
217 if ( pfunc->parcount == 2 && !mem_cmp( obj->name, "@oftype", 8 ))
218 {
219 flag = GHTY_EXTFUNC;
220 ftype = FTYPE_OFTYPE;
221 }
222 // + 1 на главный тип
223 if ( pfunc->parcount > 1 && pfunc->parcount <= MAX_MSR &&
224 !mem_cmp( obj->name, "@array", 7 ))
225 {
226 ftype = FTYPE_ARRAY + pfunc->parcount - 2;
227 flag = GHTY_ARRAY;
228 }
229 }
230 if ( obj->flag & GHBC_OPERATOR )
231 {
232 if ( pfunc->parcount == 2 && pfunc->params[1].type == TCollection &&
233 mem_cmp( obj->name, "#=", 4 ))
234 {
235 flag = GHTY_EXTFUNC;
236 ftype = FTYPE_COLLECTION;
237 }
238 }
239 if ( flag )
240 {
241 povmtype ptype = ( povmtype )PCMD( pfunc->params->type );
242 ptype->ftype[ ftype ] = obj->id;
243 ptype->vmo.flag |= flag;
244 // print("TYPE=%i ftype=%i id= %i %s\n", pfunc->params->type, ftype,
245 // obj->id, obj->name );
246 }
247 }
248 return obj;
249
250 error:
251 msg( MNameexist | MSG_VALSTRERR, obj->name, idname );
252 return NULL;
253 }
254
255 /*-----------------------------------------------------------------------------
256 *
257 * ID: load_common 19.10.06 0.0.A.
258 *
259 * Summary: Common load an object to VM.
260 *
261 -----------------------------------------------------------------------------*/
262
263 pubyte STDCALL load_common( pubyte input, pubyte* out, uint structsize )
264 {
265 pvmobj obj;
266 ubyte type = *input++;
267 uint flag = *( puint )input & 0x20FFFFFF; // ??? GHRT_ to zero
268 // except GHRT_PRIVATE
269 uint len;
270
271 input += sizeof( uint );
272
273 _vm.ipack = flag & GHCOM_PACK ? 1 : 0;
274
275 _vm.isize = load_bwd( &input );
276
277 obj = ( pvmobj )vmmng_begin( ( _vm.ipack ? 2 : 1 ) * _vm.isize );
278 mem_zero( obj, structsize );
279
280 obj->type = type;
281 obj->flag = flag;
282 *out = ( pubyte )obj + structsize;
283
284 if ( flag & GHCOM_NAME )
285 {
286 // считываем опционально имя
287 len = mem_copyuntilzero( *out, input );
288 obj->name = *out;
289
290 input += len;
291 *out += len;
292 }
293
294 return input;
295 }
296
297 /*-----------------------------------------------------------------------------
298 *
299 * ID: load_var 19.10.06 0.0.A.
300 *
301 * Summary: Load subtypes or variable
302 *
303 -----------------------------------------------------------------------------*/
304
305 pvartype STDCALL load_var( pubyte* input, pubyte* output, uint count,
306 puint size, uint align )
307 {
308 pvartype psub;
309 povmtype newtype;
310 pubyte out = *output;
311 pubyte ptr = *input;
312 pvartype ret;
313 uint i, off = 0, flag, len, k;
314
315 ret = psub = ( pvartype )out;
316
317 out += count * sizeof( vartype );
318 // print("Count=%i ---------\n", count );
319 for ( i = 0; i < count; i++ )
320 {
321 mem_zero( psub, sizeof( vartype ));
322 psub->type = load_convert( &ptr );
323 psub->off = align ? ( off >> 2 ) : off;
324 flag = *ptr++;
325 psub->flag = ( ubyte )flag;
326 if ( flag & VAR_NAME )
327 {
328 len = mem_copyuntilzero( out, ptr );
329 psub->name = out;
330 ptr += len;
331 // print(" Field %i %s\n", i, psub->name );
332 out += len;
333 }
334 newtype = ( povmtype )PCMD( psub->type );
335 off += flag & VAR_PARAM ? ( newtype->stsize << 2 ) : newtype->size;
336
337 if ( flag & VAR_OFTYPE )
338 psub->oftype = load_convert( &ptr );
339
340 psub->ptr = ( puint )out;
341
342 if ( flag & VAR_DIM )
343 {
344 len = 1;
345 psub->dim = *ptr++;
346
347 for ( k = 0; k < psub->dim; k++ )
348 {
349 *( puint )out = load_bwd( &ptr );
350 len *= *( puint )out;
351 out += sizeof( uint );
352 }
353 // Если reserved < 4 удаляем лишнее
354 if ( psub->type == TReserved )
355 off += len - 4;
356 }
357 if ( flag & VAR_DATA )
358 {
359 psub->data = 1;
360 // print("Data=%s\n", psub->name );
361 if ( newtype->vmo.flag & GHTY_STACK )
362 len = newtype->size;
363 else
364 {
365 if ( psub->type == TStr )
366 {
367 len = mem_len( ptr ) + 1;
368 // print("Val=%s\n", ptr );
369 }
370 else
371 {
372 *( puint )out = load_bwd( &ptr );
373 len = *( puint )out;
374 // print("Load %i %x\n", len, *( puint )ptr );
375 out += sizeof( uint );
376 }
377 }
378 mem_copy( out, ptr, len );
379 ptr += len;
380 out += len;
381 }
382 // Alignment
383 if ( align && ( off & 3 ))
384 off += 4 - ( off & 0x3 );
385 // print("off = %i \n", off );
386
387 psub++;
388 }
389 *size = off;
390
391 *output = out;
392 *input = ptr;
393 return ret;
394 }
395
396 /*-----------------------------------------------------------------------------
397 *
398 * ID: load_stack 26.12.06 0.0.A.
399 *
400 * Summary: Load stack object
401 *
402 -----------------------------------------------------------------------------*/
403
404 pvmobj STDCALL load_stack( int top, int cmd, stackfunc pseudo )
405 {
406 povmstack pstack = ( povmstack )vmmng_begin( sizeof( ovmstack ));
407
408 mem_zero( pstack, sizeof( ovmstack ));
409 pstack->vmf.vmo.type = pseudo ? OVM_PSEUDOCMD : OVM_STACKCMD;
410 pstack->vmf.vmo.flag = GHRT_MAYCALL;
411 pstack->topshift = top;
412 pstack->cmdshift = cmd;
413 pstack->vmf.func = ( pvoid )pseudo;
414 load_addobj( 0 );
415 vmmng_end( ( pubyte )( pstack + 1 ));
416
417 return ( pvmobj )pstack;
418 }
419
420 /*-----------------------------------------------------------------------------
421 *
422 * ID: load_type 26.12.06 0.0.A.
423 *
424 * Summary: Load type object
425 *
426 -----------------------------------------------------------------------------*/
427
428 pvmobj STDCALL load_type( pubyte* input )
429 {
430 povmtype ptype;
431 pubyte out;
432 pubyte ptr = *input;
433
434 ptr = load_common( ptr, &out, sizeof( ovmtype ) );
435
436 ptype = ( povmtype )_vm.pmng->top;
437 ptype->size = 4;
438 ptype->stsize = 1;
439 ptype->index.type = 0;//TUint;
440
441 if ( ptype->vmo.flag & GHTY_INHERIT )
442 {
443 povmtype inherit;
444
445 ptype->inherit = load_convert( &ptr );
446 inherit = ( povmtype )PCMD( ptype->inherit );
447 // Наследуем index type от родителя
448 ptype->index.type = inherit->index.type;
449 ptype->index.oftype = inherit->index.oftype;
450 ptype->ftype[ FTYPE_OFTYPE ] = inherit->ftype[ FTYPE_OFTYPE ];
451 }
452 if ( ptype->vmo.flag & GHTY_INDEX )
453 {
454 ptype->index.type = load_convert( &ptr );
455 ptype->index.oftype = load_convert( &ptr );
456 }
457 if ( ptype->vmo.flag & GHTY_INITDEL )
458 {
459 ptype->ftype[ FTYPE_INIT ] = load_convert( &ptr );
460 ptype->ftype[ FTYPE_DELETE ] = load_convert( &ptr );
461 }
462 if ( ptype->vmo.flag & GHTY_EXTFUNC )
463 {
464 ptype->ftype[ FTYPE_OFTYPE ] = load_convert( &ptr );
465 ptype->ftype[ FTYPE_COLLECTION ] = load_convert( &ptr );
466 }
467 if ( ptype->vmo.flag & GHTY_ARRAY )
468 {
469 uint i, dim = load_convert( &ptr );
470
471 if ( dim <= MAX_MSR )
472 {
473 for ( i = 0; i < dim; i++ )
474 ptype->ftype[ FTYPE_ARRAY + i ] = load_convert( &ptr );
475 }
476 else
477 ptype->ftype[ FTYPE_ARRAY ] = dim;
478 }
479 ptype->count = load_bwd( &ptr );
480 if ( ptype->vmo.flag & GHTY_STACK )
481 {
482 ptype->size = ptype->count;
483 ptype->stsize = ptype->size > sizeof( uint ) ? 2 : 1;
484 ptype->count = 0;
485 }
486 else
487 if ( ptype->count )
488 {
489 ptype->children = load_var( &ptr, &out, ptype->count, &ptype->size, 0 );
490 }
491
492 load_addobj( 0 );
493 vmmng_end( out );
494
495 // print("id= %i name= %s s=%i/%i ind = %i\n", ptype->vmo.id, ptype->vmo.name, ptype->size,
496 // ptype->stsize, ptype->index.type );
497 *input += _vm.isize;
498 return ( pvmobj )ptype;
499 }
500
501 /*-----------------------------------------------------------------------------
502 *
503 * ID: load_commonfunc 26.12.06 0.0.A.
504 *
505 * Summary: Common Load bytecode or func object
506 *
507 -----------------------------------------------------------------------------*/
508
509 pvmfunc STDCALL load_commonfunc( pubyte* input, pubyte* out, pubyte* end, puint size )
510 {
511 pvmfunc pfunc;
512 pubyte ptr = *input;
513 uint i;
514
515 // Проверка на повторный вызов
516 ptr = load_common( ptr, out, *size );
517 *end = *input + _vm.isize;
518
519 pfunc = ( pvmfunc )_vm.pmng->top;
520 pfunc->vmo.flag |= GHRT_MAYCALL;
521 pfunc->ret = load_var( &ptr, out, 1, size, 1 );
522 pfunc->dwret = ( ubyte )(( povmtype )PCMD( pfunc->ret->type ))->stsize;
523 pfunc->parcount = ( ubyte )load_bwd( &ptr );
524 if ((uint)*out & 3 ) // Alignment
525 *out += 4 - ( (uint)*out & 3 );
526
527 // print("ret=%i %s %i\n", pfunc->ret->type,pfunc->vmo.name, pfunc->parcount );
528 pfunc->params = load_var( &ptr, out, pfunc->parcount, size, 1 );
529
530 for ( i = 0; i < pfunc->parcount; i++ )
531 {
532 pfunc->parsize += ( ubyte )((povmtype)PCMD( pfunc->params[i].type ))->stsize;//( ubyte )( *size >> 2 );
533 }
534 // print("%s ret = %i parsize = %i count = %i\n",
535 // pfunc->vmo.name, pfunc->ret->type, pfunc->parsize, pfunc->parcount );
536
537 *input = ptr;
538
539 return pfunc;
540 }
541
542
543 /*-----------------------------------------------------------------------------
544 *
545 * ID: load_bytecode 26.12.06 0.0.A.
546 *
547 * Summary: Load bytecode object
548 *
549 -----------------------------------------------------------------------------*/
550
551 pvmobj STDCALL load_bytecode( pubyte* input, uint mode )
552 {
553 povmbcode pbcode;
554 pvmobj ret;
555 pubyte out, end;
556 puint bcout;
557 pubyte ptr = *input;
558 uint size = sizeof( ovmbcode );
559 uint i, off, cmd;
560 // uint nobcode = 0; // 1 if there is not bytecode
561
562 _vm.loadmode = mode;
563 pbcode = ( povmbcode )load_commonfunc( &ptr, &out, &end, &size );
564 // print( "OK %s\n", pbcode->vmf.vmo.name );
565
566 pbcode->setcount = ( ubyte )load_bwd( &ptr );
567
568 if ( pbcode->setcount )
569 {
570 pbcode->sets = ( pvarset )out;
571 out += sizeof( varset ) * pbcode->setcount;
572 off = 0;
573 for ( i = 0; i < pbcode->setcount; i++ )
574 {
575 pbcode->sets[i].count = ( ushort )load_bwd( &ptr );
576 pbcode->sets[i].first = ( ushort )off;
577 off += pbcode->sets[i].count;
578 }
579 pbcode->vars = load_var( &ptr, &out, off, &size, 1 );
580 pbcode->varsize = size >> 2;
581 off = 0;
582
583 // Sets summary size of block local variables in uints
584 for ( i = 0; i < ( uint )( pbcode->setcount - 1 ); i++ )
585 {
586 pbcode->sets[i].off = off;
587 pbcode->sets[i].size =
588 pbcode->vars[ pbcode->sets[ i + 1 ].first ].off - off;
589 off += pbcode->sets[i].size;
590 }
591 pbcode->sets[ i ].size = pbcode->varsize - off;
592 pbcode->sets[ i ].off = off;
593 }
594 // if ( ptr == end )
595 // nobcode = 1;
596 // else
597 if ( ptr < end || mode == VMLOAD_GE )
598 {
599 // if ((uint)out & 3 )
600 out += 4 - ( (uint)out & 3 ); // Alignment
601 pbcode->vmf.func = out;
602 }
603 // print("0 %x == %x varsize = %i \n set= %i ret = %i parsize = %i count = %i\n",
604 //ptr, end, pbcode->varsize, pbcode->setcount,
605 // pbcode->vmf.ret->type, pbcode->vmf.parsize, pbcode->vmf.parcount );
606 // Loading byte-code
607 if ( mode == VMLOAD_GE )
608 {
609 bcout = ( puint )out;
610 while ( ptr < end )
611 {
612 cmd = load_convert( &ptr );
613 //print("Load=%x\n", cmd );
614 *bcout++ = cmd;
615 if ( cmd >= CNop && cmd < CNop + STACK_COUNT )
616 switch ( cmd )
617 {
618 case CQwload:
619 *bcout++ = *( puint )ptr;
620 ptr += sizeof( uint );
621 case CDwload:
622 *bcout++ = *( puint )ptr;
623 ptr += sizeof( uint );
624 break;
625 case CByload:
626 *( bcout - 1 ) = CDwload;
627 *bcout++ = *( pubyte )ptr;
628 ptr += sizeof( ubyte );
629 break;
630 case CShload:
631 *( bcout - 1 ) = CDwload;
632 *bcout++ = *( pushort )ptr;
633 ptr += sizeof( ushort );
634 break;
635 case CDwsload:
636 i = load_bwd( &ptr );
637 *bcout++ = i;
638 i <<= 2;
639 mem_copy( bcout, ptr, i );
640 bcout += *( bcout - 1 );
641 ptr += i;
642 break;
643 case CResload:
644 *bcout++ = load_bwd( &ptr ) + _vm.irescnv;
645 break;
646 case CCmdload:
647 case CPtrglobal:
648 *bcout++ = load_convert( &ptr );
649 break;
650 case CDatasize:
651 i = load_bwd( &ptr );
652 *bcout++ = i;
653 mem_copy( bcout, ptr, i );
654 bcout += ( i >> 2 ) + ( i & 3 ? 1 : 0 );
655 ptr += i;
656 // Зануляем последние добавочные байты
657 i &= 3;
658 if ( i )
659 {
660 i = 4 - i;
661 mem_zero( ( pubyte )bcout - i, i );
662 }
663 break;
664 default:
665 switch ( shifts[ cmd - CNop ] )
666 {
667 case SH1_3:
668 case SH2_3:
669 *bcout++ = load_bwd( &ptr );
670 case SHN1_2:
671 case SH0_2:
672 case SH1_2:
673 *bcout++ = load_bwd( &ptr );
674 break;
675 }
676 }
677 }
678 // Если у функции в конце нет команды возврата, то добавляем ее
679 if ( *( bcout - 1 ) != CReturn )
680 *bcout++ = CReturn;
681
682 out = ( pubyte )bcout;
683 }
684 else
685 while ( ptr < end )
686 *out++ = *ptr++;
687
688 if ( pbcode->vmf.func )
689 pbcode->bcsize = out - ( pubyte )pbcode->vmf.func;
690 // print("Add=%s\n", pbcode->vmf.vmo.name );
691 ret = load_addobj( 0 );
692 if ( ret == ( pvmobj )pbcode )
693 vmmng_end( out );
694 // Проверка на методы для типов
695
696 // print("id= %i name= %s \n", ret->id, ret->name );
697 *input += _vm.isize;
698 return ret;
699 }
700
701 /*-----------------------------------------------------------------------------
702 *
703 * ID: load_bytecode 26.12.06 0.0.A.
704 *
705 * Summary: Load bytecode object
706 *
707 -----------------------------------------------------------------------------*/
708
709 pvmobj STDCALL load_exfunc( pubyte* input, uint over )
710 {
711 povmfunc pfunc;
712 pvmobj pvmo;
713 pubyte out, end;
714 pubyte ptr = *input;
715 uint size = sizeof( ovmfunc );
716 // Проверка на повторный вызов ???
717
718 _vm.loadmode = VMLOAD_EXTERN;
719
720 pfunc = ( povmfunc )load_commonfunc( &ptr, &out, &end, &size );
721
722 if ( pfunc->vmf.vmo.name )
723 switch ( pfunc->vmf.vmo.name[0] )
724 {
725 case '@': pfunc->vmf.vmo.flag |= GHBC_METHOD; break;
726 case '#': pfunc->vmf.vmo.flag |= GHBC_OPERATOR; break;
727 }
728 if ( pfunc->vmf.vmo.flag & GHEX_IMPORT )
729 {
730 pfunc->import = load_convert( &ptr );
731 pfunc->original = out;
732 size = mem_copyuntilzero( out, ptr );
733 ptr += size;
734 out += size;
735 // print("LOAD %x == %s %s\n", pfunc->import, pfunc->original, pfunc->vmf.vmo.name );
736 }
737 if ( pfunc->vmf.ret->type == TDouble || pfunc->vmf.ret->type == TFloat )
738 pfunc->vmf.vmo.flag |= GHEX_FLOAT;
739 // print("1 %x == %x nofunc = %i\n", ptr, end, nofunc );
740 // print("Over = %i mode=%i name=%s\n", over, _vm.loadmode, pfunc->vmf.vmo.name );
741 pvmo = load_addobj( over );
742 /* if ( pfunc->vmf.vmo.flag & GHEX_CDECL )
743 print("id= %i next = %i name= %s count=%i %i/%i\n", pfunc->vmf.vmo.id,
744 pfunc->vmf.vmo.nextname, pfunc->vmf.vmo.name,
745 pfunc->vmf.parsize, pfunc->vmf.parcount, pfunc->vmf.ret->type );
746 */
747 if ( ( pvmobj )pfunc == pvmo )
748 vmmng_end( out );
749 // // Проверка на методы для типов
750 *input += _vm.isize;
751
752 return pvmo;
753 }
754
755 /*-----------------------------------------------------------------------------
756 *
757 * ID: load_define 26.12.06 0.0.A.
758 *
759 * Summary: Load define object
760 *
761 -----------------------------------------------------------------------------*/
762
763 pvmobj STDCALL load_define( pubyte* input )
764 {
765 // Добавляем объект
766 povmdefine pdefine;
767 pubyte out;
768 uint size;
769 pubyte ptr = *input;
770
771 ptr = load_common( ptr, &out, sizeof( ovmdefine ) );
772
773 pdefine = ( povmdefine )_vm.pmng->top;
774
775 pdefine->count = load_bwd( &ptr );
776 if ( pdefine->count )
777 {
778 pdefine->macros = load_var( &ptr, &out, pdefine->count, &size, 0 );
779 }
780
781 load_addobj( 0 );
782 vmmng_end( out );
783 // print("id= %i name= %s \n", pdefine->vmo.id, pdefine->vmo.name );
784 *input += _vm.isize;
785 #ifndef RUNTIME
786 if ( _vm.loadmode == VMLOAD_GE && _compile )
787 {
788 lexem group, item;
789 uint namedef, i, idname = 0;
790 pmacro pm;
791 pstr ps;
792 pbuf pb;
793 pubyte data;
794
795 mem_zero( &group, sizeof( lexem ));
796 if ( pdefine->vmo.name && pdefine->vmo.name[0] )
797 {
798 group.type = LEXEM_NAME;
799 group.nameid = ( uint )hash_create( &_compile->names, pdefine->vmo.name )->id;
800 idname = group.nameid + 1;
801 }
802 namedef = LEXEM_NUMBER | ( pdefine->vmo.flag & GHDF_NAMEDEF ? MACRO_NAMEDEF : 0 );
803
804 if ( group.type )
805 macro_set( &group, namedef, 0 )->flag = MACROF_GROUP;
806
807 for ( i = 0; i < pdefine->count; i++ )
808 {
809 item.type = LEXEM_NAME;
810 // print("name=%s\n", pdefine->macros[i].name );
811 item.nameid = hash_create( &_compile->names, pdefine->macros[i].name )->id;
812 pm = macro_set( &item, namedef, idname );
813 data = ( pubyte )( pdefine->macros[i].ptr + pdefine->macros[i].dim );
814 switch ( pdefine->macros[i].type )
815 {
816 case TStr:
817 if ( pdefine->macros[i].flag & VAR_IDNAME )
818 {
819 pm->mr.vallexem.type = LEXEM_NAME;
820 pm->mr.vallexem.nameid = ( uint )hash_create( &_compile->names,
821 data );
822 }
823 else
824 {
825 pm->mr.vallexem.type = LEXEM_STRING;
826 ps = str_init( ( pstr )arr_append( &_compile->string ));
827 str_copyzero( ps, data );
828 // print("Data=%s\n", data );
829 pm->mr.vallexem.strid = arr_count( &_compile->string ) - 1;
830 }
831 break;
832 case TBuf:
833 pm->mr.vallexem.type = LEXEM_BINARY;
834 pb = buf_init( ( pbuf )arr_append( &_compile->binary ));
835 buf_copy( pb, data + sizeof( uint ), *( puint )data );
836 // print("Data=%s\n", data );
837 pm->mr.vallexem.binid = arr_count( &_compile->binary ) - 1;
838 break;
839 default: // Numbers
840 pm->mr.vallexem.type = LEXEM_NUMBER;
841 pm->mr.vallexem.num.type = pdefine->macros[i].type;
842 mem_copy( ( pubyte )&pm->mr.vallexem.num.vint, data,
843 (( povmtype )PCMD( pdefine->macros[i].type ))->size );
844 break;
845 }
846 }
847 }
848 #endif
849 return ( pvmobj )pdefine;
850 }
851
852 /*-----------------------------------------------------------------------------
853 *
854 * ID: load_import 26.12.06 0.0.A.
855 *
856 * Summary: Load import object
857 *
858 -----------------------------------------------------------------------------*/
859
860 pvmobj STDCALL load_import( pubyte* input )
861 {
862 povmimport pimport;
863 pubyte out;
864 uint len;
865 pubyte ptr = *input;
866
867 ptr = load_common( ptr, &out, sizeof( ovmimport ) );
868
869 pimport = ( povmimport )_vm.pmng->top;
870 len = mem_copyuntilzero( out, ptr );
871 pimport->filename = out;
872 ptr += len;
873 out += len;
874
875 if ( pimport->vmo.flag & GHIMP_LINK )
876 {
877 pimport->size = *( puint )ptr;
878 ptr += sizeof( uint );
879
880 mem_copy( out, ptr, pimport->size );
881 pimport->data = out;
882 out += pimport->size;
883 // print("Load import %i %s\n", pimport->size, pimport->filename );
884 }
885
886 load_addobj( 0 );
887 vmmng_end( out );
888 // print("id= %i name= %s \n", pdefine->vmo.id, pdefine->vmo.name );
889 *input += _vm.isize;
890
891 return ( pvmobj )pimport;
892 }
893
894 /*-----------------------------------------------------------------------------
895 *
896 * ID: load_global 26.12.06 0.0.A.
897 *
898 * Summary: Load global variable object
899 *
900 -----------------------------------------------------------------------------*/
901
902 pvmobj STDCALL load_global( pubyte* input )
903 {
904 povmglobal pglobal;
905 pubyte out;
906 uint size;
907 pubyte ptr = *input;
908
909 ptr = load_common( ptr, &out, sizeof( ovmglobal ));
910
911 pglobal = ( povmglobal )_vm.pmng->top;
912 pglobal->type = load_var( &ptr, &out, 1, &size, 1 );
913 pglobal->pval = out;
914 out += max( sizeof( uint ), (( povmtype )PCMD( pglobal->type->type ))->size );
915 load_addobj( 0 );
916 vmmng_end( out );
917 // print("GLOBAL id= %i name= %s %i\n", pglobal->vmo.id, pglobal->vmo.name,
918 // (( povmtype )PCMD( pglobal->type->type ))->size );
919 *input += _vm.isize;
920
921 return ( pvmobj )pglobal;
922 }
923
924 /*-----------------------------------------------------------------------------
925 *
926 * ID: load_alias 26.12.06 0.0.A.
927 *
928 * Summary: Load alias object
929 *
930 -----------------------------------------------------------------------------*/
931
932 pvmobj STDCALL load_alias( pubyte* input )
933 {
934 povmalias palias;
935 pubyte out;
936 // uint size;
937 pubyte ptr = *input;
938
939 ptr = load_common( ptr, &out, sizeof( ovmalias ));
940
941 palias = ( povmalias )_vm.pmng->top;
942 palias->idlink = load_convert( &ptr );
943 load_addobj( 0 );
944 vmmng_end( out );
945 *input += _vm.isize;
946
947 return ( pvmobj )palias;
948 }
949
950 //-----------------------------------------------------------------------------