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