EnglishРусский  

   ..

   common.c

   common.h

   gefile.h

   geload.c

   gesave.c

   types.h

   vm.c

   vm.h

The project is closed! You can look at a new scripting language. It is available on GitHub.
Also, try our open source cross-platform automation software.

Ads

Installer and installation software
Commercial and Freeware installers.

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