EnglishРусский  

   ..

   vm.c

   vm.h

   vmload.c

   vmload.h

   vmres.c

   vmres.h

   vmrun.c

   vmrun.h

   vmtype.c

   vmtype.h

Ads

Perfect Automation tool
All-In-One: Script editor, Launcher, Scheduler, Keyboard & Mouse Recorder. Try now!

CreateInstall
Freeware and commercial installers.

Cell Phone Batteries
Batteries Plus offers batteries for laptop, camcorder, cell phone, camera.

Gentee needs your help!
How to advertise with us
 
laptop battery

source\src\vm\vmload.c
  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 //-----------------------------------------------------------------------------
Edit