EnglishРусский  

   ..

   vm.c

   vm.h

   vm-a.h

   vmload.c

   vmload.h

   vmres.c

   vmres.h

   vmrun.c

   vmrun.h

   vmrun-a.c

   vmtype.c

   vmtype.h

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

  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: vm 18.10.06 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov ( gentee )
 13 *
 14 * Summary: 
 15 * 
 16 ******************************************************************************/
 17 
 18 #include "vm.h"
 19 #include "vmrun.h"
 20 #include "vmmanage.h"
 21 #include "vmload.h"
 22 #include "vmtype.h"
 23 #include "vmres.h"
 24 #include "../bytecode/bytecode.h"
 25 #include "../bytecode/funclist.h"
 26 #include "../common/file.h"
 27 #include "../genteeapi/gentee.h"
 28 
 29 vm  _vm;   // Global virtual machine
 30 pvm _pvm;  // Pointer to VM
 31 
 32 /*-----------------------------------------------------------------------------
 33 *
 34 * ID: vm_deinit 19.10.06 0.0.A.
 35 * 
 36 * Summary: Initialize the virtual machine.
 37 *  
 38 -----------------------------------------------------------------------------*/
 39 
 40 void  STDCALL vm_deinit( void )// pvm _pvm )
 41 {
 42    povmglobal  global;
 43    povmimport  import;
 44    pvmobj      vmobj;
 45    uint        i;
 46 
 47    // Destroy global parameters
 48 //   for ( i = 1024; i < arr_count( &_vm.objtbl ); i++ )
 49    for ( i = arr_count( &_vm.objtbl ) - 1; i >= 1024; i-- )
 50    {
 51       vmobj = ( pvmobj )PCMD( i );
 52       if ( vmobj->type == OVM_GLOBAL && vmobj->flag & GHRT_LOADED )
 53       {
 54          global = ( povmglobal )vmobj;
 55          type_vardelete( global->pval, global->type, 1, 0 );
 56       }
 57       if ( vmobj->type == OVM_IMPORT )
 58       {
 59          import = ( povmimport )vmobj;
 60          if ( import->handle )
 61          {
 62          #ifdef LINUX
 63             dlclose( import->handle );
 64          #else
 65             FreeLibrary( import->handle );
 66          #endif
 67          }
 68       }
 69    }
 70    // Destroy all objects
 71    arr_delete( &_vm.objtbl );
 72    hash_delete( &_vm.objname );
 73    collect_delete( &_vm.resource );
 74    buf_delete( &_vm.resource.data );
 75    vmmng_destroy( );
 76 /*  
 77    #ifdef GEGUI
 78       gui_deinit();
 79    #endif
 80 
 81    // Освобождаем глобальные переменные
 82    buf_destroy( vm->entry );
 83    lge_deinit( &vm->lge );
 84    collect_destroy( &vm->collect );
 85    systbl_deinit( &vm->objmem );
 86    systbl_deinit( &vm->objtbl );
 87    nametbl_deinit( &vm->nametbl );
 88    mem_free( vm->exception );*/
 89 }
 90 
 91 /*-----------------------------------------------------------------------------
 92 *
 93 * ID: vm_init 19.10.06 0.0.A.
 94 * 
 95 * Summary: Initialize the virtual machine.
 96 *  
 97 -----------------------------------------------------------------------------*/
 98 
 99 void  STDCALL vm_init( void  )
100 {
101    uint       i, id, k, len, flag;
102    stackfunc  pseudo;
103    int        topshift, cmdshift;
104    pubyte     emb, ptr = ( pubyte )&embtypes;
105    ubyte      input[64];
106    pvmfunc    pfunc;
107 //   povmstack  pstack;
108   
109    _pvm = &_vm;
110    mem_zero( _pvm, sizeof( vm ));
111    _vm.loadmode = 1;
112    // Initialize the array of objects
113    arr_init( &_vm.objtbl, sizeof( uint ));
114    arr_step( &_vm.objtbl, 1024 );
115    buf_init( &_vm.resource.data );
116    // Initialize the hash of object names
117    hash_init( &_vm.objname, sizeof( uint ));
118    vmmng_new();
119 
120    // Add zero command
121    load_stack( 0, 0, NULL )->type = OVM_NONE;
122 
123    // Loading kernel objects into VM
124    for ( i = TInt; i <= TFordata; i++ )
125    {
126 //      load_stack( 0, 0, NULL )->type = OVM_TYPE;
127       load_type( &ptr );
128 //      vm_addobj( _pvm, ( pvmobj )mem_allocz( sizeof( vmobj )), 0 );
129    }
130    // Loading kernel objects into VM
131    for ( i = 0; i < STACK_COUNT; i++ )
132    {
133       topshift = 0;
134       cmdshift = 0;
135       pseudo = NULL;
136       switch ( shifts[i] )
137       {
138          case SHN3_1: topshift--;
139          case SHN2_1: topshift--;
140          case SHN1_1: topshift--;
141             cmdshift = 1;
142             break;
143          case SHN1_2: topshift--;
144             cmdshift = 2;
145             break;
146          case SH0_2:  cmdshift++;
147          case SH0_1:  cmdshift++;
148             break;
149          case SH1_3:  cmdshift++;
150          case SH1_2:  cmdshift++;
151          case SH1_1:  cmdshift++;
152             topshift = 1;
153             break;
154          case SH2_1:
155             topshift = 2;
156             cmdshift = 1;
157             break;
158          case SH2_3:
159             topshift = 2;
160             cmdshift = 3;
161             break;
162       }
163       id = _vm.count;
164       if ( id >= CMulII ) // > CReturn )
165       {
166          if ( id <= Cui2l )
167             pseudo = pseudo_i;
168          else if ( id <= CNotUL )
169                 pseudo = pseudo_ul;
170          else if ( id <= CRightUL )
171                 pseudo = pseudo_pul;
172          else if ( id <= CGreaterLL )
173                 pseudo = pseudo_l;
174          else if ( id <= CRightL )
175                 pseudo = pseudo_pl;
176          else if ( id <= CEqFF )
177                 pseudo = pseudo_f;
178          else if ( id <= CDivF )
179                 pseudo = pseudo_pf;
180          else if ( id <= CEqDD )
181                 pseudo = pseudo_d;
182          else if ( id <= CDivD )
183                 pseudo = pseudo_pd;
184          else if ( id <= CRightUS )
185                 pseudo = pseudo_ui;
186          else if ( id == CCollectadd )
187                 pseudo = pseudo_collectadd;
188       }
189       load_stack( topshift, cmdshift, pseudo );
190    }
191 //   print("Count=%i \n", _vm.count );
192    emb = ( pubyte )&embfuncs;
193    flag = GHCOM_NAME | GHCOM_PACK;
194 
195    for ( i = 0; i < FUNCCOUNT; i++ )
196    {
197       if ( !mem_cmp( emb, "sin", 3 ))
198          flag |= GHEX_CDECL;
199 
200       ptr = ( pubyte )&input;
201       *ptr++ = OVM_EXFUNC;
202       *(( puint )ptr)++ = flag;
203       *ptr++ = 0;
204       len = mem_copyuntilzero( ptr, emb );
205       ptr += len;
206       emb += len;
207       id = *emb++;
208       *ptr++ = ( id & 0x80 ? *emb++ : 0 );
209       *ptr++ = 0;
210       id &= 0x7f;
211       *ptr++ = ( ubyte )id;
212       for ( k = 0; k < id; k++ )
213       {
214          *ptr++ = *emb++;
215          *ptr++ = 0;
216       }
217       input[ 5 ] = ( ubyte )( ptr - ( pubyte )&input );
218       ptr = ( pubyte )&input;
219 
220       pfunc = ( pvmfunc )load_exfunc( &ptr, 0 );
221       pfunc->func = embfuncaddr[ i ];
222    }
223 //   print("Count=%i \n", _vm.count );
224    // Loading reserved empty commands
225    while ( _pvm->count < KERNEL_COUNT )
226       load_stack( 0, 0, NULL )->type = OVM_NONE;
227 
228    _vm.countinit = 0;//KERNEL_COUNT;
229 //   _vm.stacksize = 0x80000; // The default stack size = 512 КБ
230 
231 /* systbl_init( &vm->objmem, 0, STBL_INIT );
232    vm->objmem.numtbl = 1024;
233    // Резервируем нулевой элемент
234    systbl_appenddw( &vm->objmem, 0 );
235    // Инициализируем коллекцию для удаления
236    i = 0;
237    collect_new( ( pbyte )&i, &vm->collect );
238 
239    lge_init( vm );
240 
241    vm->stacksize = 0x80000; // Размер стэка 512 КБ
242    vm->entry = buf_new( NULL, 64 );
243    local_addstack( vm, vm_nocmd, 0 );
244 
245    i = 0;
246    while ( fromtocmd[ i ].from )
247    {
248       for ( j = fromtocmd[ i ].from; j <= fromtocmd[ i ].to; j++ )
249          local_addstack( vm, idcmd[i], j );
250       i++;
251    }
252    for ( i = SByteSign; i < SLast; i++ )
253       local_addtype( vm, i );
254   
255 //   print("Last cmd=%i %i\n", SByteSign, SLast );
256 //   for ( i = FPrintDw + 1; i < 256; i++ )
257    for ( i = SLast; i < 256; i++ )
258       local_addstack( vm, vm_nocmd, i );
259 
260    for ( i = FMemAlloc; i <= FPrintDw; i++ )
261       local_addfunc( vm, i - FMemAlloc );
262 
263    #ifdef GEGUI
264       gui_init( vm );
265    #endif
266 //   print("Now=%i\n", vm->objtbl.count );
267    for ( i = vm->objtbl.count; i < 1024; i++ )
268       local_addstack( vm, vm_nocmd, i );
269    vm->link = LINKID - 1;
270    vm->rtlast = vm->objtbl.count - 1;
271 
272    vm->exception = mem_alloc( sizeof( sexception ) * EXCEPT_LIMIT );
273    vm->lastexcept = vm->exception;
274    vm->lastexcept->start = ( pdword )MAX_DWORD;
275    vm->lastexcept->idfunc = 0;
276 //   vm->idlast = vm->rtlast;*/
277 }
278 
279 /*-----------------------------------------------------------------------------
280 *
281 * ID: vm_find 19.10.06 0.0.A.
282 * 
283 * Summary: Find the byte-code object
284 * 
285 * pars - type + oftype
286 *  
287 -----------------------------------------------------------------------------*/
288 
289 pvmfunc  STDCALL vm_find( pubyte name, uint count, puint pars )
290 {
291    pvmfunc      bcode, best = NULL;
292    pvartype     par;
293    uint         result = 0, countpars = 0, bestweight = 0;
294    uint         i, weight, k, idtype, idof ;
295    puint        curpar;
296    phashitem    phi = NULL;
297 
298    phi = hash_find( &_vm.objname, name );
299 
300    if ( !phi || !( result = *( puint )( phi + 1 ) ))
301       return ( pvmfunc )MUnkoper;
302 
303 //   result = *( puint )( phi + 1 );
304       
305    while ( result )
306    {
307       bcode =  ( pvmfunc )PCMD( result );
308 //      print( "Look for %s = %i next=%i\n", name, result, bcode->vmo.nextname );
309       if ( !( bcode->vmo.flag & GHRT_MAYCALL ))
310          return best;
311 //      print( "Look for %s = %i next=%i\n", name, result, bcode->vmo.nextname );
312       if ( bcode->parcount == count + ( bcode->vmo.flag & GHBC_RESULT ? 1 : 0 ))
313       {
314          countpars = 1;
315          par = bcode->params;
316          // Делаем проверку типов
317          if ( !bcode->parcount || ( bcode->parcount == 1 && ( bcode->vmo.flag & GHBC_RESULT )))
318          {
319             best = bcode;
320             break;
321          }
322          weight = 0;
323          curpar = pars;
324          for ( i = 0; i < count; i++ )
325          {
326             k = 0;
327             idtype = *curpar++;
328             idof = *curpar++;
329 
330             if ( !idtype )
331             {
332                weight = 0;
333                break;
334             }
335             k = type_compat( idtype, par->type, 0 );
336             // Проверка на of type.
337             if ( k && par->oftype && !type_compat( idof, par->oftype, 1 ))
338                k = 0;
339 
340 //            print( "COMP %i= %i %i\n", SUInt, par->type->vmobj.id, *curpar );
341 /*            if ( par->type == idtype || idtype == TAny || par->type == TAny )
342                k = 100;
343             else 
344                if ( par->type <= TUlong && idtype <= TUlong )
345                   k = compnum[ par->type - TInt ][ idtype - TInt ];
346                else
347                {
348                   if ( type_isinherit( idtype, par->type ))
349                      k = 45;
350                }
351             // Проверка на of type.
352             if ( par->oftype && par->oftype != idof )
353                if ( par->oftype <= TUlong && idof <= TUlong )
354                {
355                   if ( !compnum[ par->oftype - TInt ][ idof - TInt ] ||
356                      (( povmtype )PCMD( par->oftype ))->size != 
357                      (( povmtype )PCMD( idof ))->size )
358                      k = 0;
359                }
360                else
361                {
362                   if ( !type_isinherit( idof, par->oftype ))
363                      k = 0;
364                }
365 */
366             if ( !k )
367             {
368                weight = 0;
369                break;
370             }
371             weight += k; //+ ( k != 100 ? 2 * i : 0 );// - 2 * i;
372             // следующий параметр у функции
373             par++;
374          }
375 //         print("%s %i weight = %i\n", name, ( dword )bcode->vmobj.id, weight );
376          if ( weight > bestweight )
377          {
378             best = bcode;
379             bestweight = weight;
380             if ( bestweight == ( uint )bcode->parcount * 100 )
381             {
382 //               print("Best\n");
383                return best;
384             }
385          }
386       }
387       result = bcode->vmo.nextname;
388    }
389    if ( !countpars )
390       return ( pvmfunc )MCountpars;
391 
392    if ( !best )
393       return ( pvmfunc )MTypepars;
394 
395    return best;
396 }
397 
398 /*-----------------------------------------------------------------------------
399 *
400 * ID: import_execute 23.10.06 0.0.A.
401 * 
402 * Summary: This function loads import library
403 *
404 -----------------------------------------------------------------------------*/
405 
406 void  STDCALL import_execute( povmimport pimport )
407 {
408    str  filename;
409    str  original;
410 
411    str_init( &filename );
412    str_init( &original );
413 
414    str_copyzero( &original, pimport->filename );
415    if ( pimport->vmo.flag & GHIMP_LINK )
416    {
417       uint    handle;
418 
419       gettempfile( &filename, &original );
420       if ( pimport->size )
421       {
422          handle = os_fileopen( &filename, FOP_CREATE | FOP_EXCLUSIVE );
423          if ( !handle )
424             msg( MFileopen | MSG_STR | MSG_EXIT, &filename );
425 
426          if ( !os_filewrite( handle, pimport->data, pimport->size ))
427             msg( MFilewrite | MSG_STR | MSG_EXIT, &filename );
428          os_fileclose( handle );
429       }
430    }
431    else
432       if ( pimport->vmo.flag & GHIMP_EXE )
433          getmodulepath( &filename, &original );
434       else
435          str_copy( &filename, &original );
436 
437    if ( str_len( &filename ))
438    {
439       #ifdef LINUX
440          pimport->handle = dlopen( dir, RTLD_LAZY );
441       #else
442          pimport->handle = LoadLibrary( str_ptr( &filename ));
443       #endif
444    }
445    else
446    {
447       pimport->handle = _gentee.export ? ( pvoid )0xFFFFFFFF : GetModuleHandle( NULL );
448    }
449 //   print("Import=%x %s\n", pimport->handle, str_ptr( &filename ));
450    str_delete( &filename );
451    str_delete( &original );
452 }
453 
454 /*-----------------------------------------------------------------------------
455 *
456 * ID: exfunc_execute 23.10.06 0.0.A.
457 * 
458 * Summary: This function loads functions from libraries
459 *
460 -----------------------------------------------------------------------------*/
461 
462 void  STDCALL exfunc_execute( povmfunc pfunc )
463 {
464    pvoid handle;
465 
466    if ( !pfunc->import )
467       return;
468    handle = (( povmimport )PCMD( pfunc->import ))->handle;
469    if ((( pvmobj )PCMD( pfunc->import ))->flag & GHIMP_CDECL )
470    {
471       pfunc->vmf.vmo.flag |= GHEX_CDECL;
472    }
473    if ( handle )
474       if ( handle == ( pvoid )0xFFFFFFFF )
475          pfunc->vmf.func = _gentee.export( pfunc->original );
476       else
477          pfunc->vmf.func = GetProcAddress( handle, pfunc->original );
478 //   print("HANDLE=%x func=%X name=%s\n", handle, pfunc->vmf.func, pfunc->vmf.vmo.name );
479 }
480 
481 /*-----------------------------------------------------------------------------
482 *
483 * ID: global_execute 23.10.06 0.0.A.
484 * 
485 * Summary: This function initialize global variables
486 *
487 -----------------------------------------------------------------------------*/
488 
489 void  STDCALL global_execute( povmglobal pglobal )
490 {
491 //   print("0 %x %x %s size = %i\n", pglobal->pval, pglobal->type, 
492 //             ((pvmobj)pglobal)->name, ((povmtype)PCMD(pglobal->type->type))->size );
493    type_varinit( pglobal->pval, pglobal->type, 1, 1 );
494    pglobal->vmo.flag |= GHRT_LOADED;
495 }
496 
497 /*-----------------------------------------------------------------------------
498 *
499 * ID: vm_execute 23.10.06 0.0.A.
500 * 
501 * Summary: This function execute the loaded byte-code
502 *
503 -----------------------------------------------------------------------------*/
504 
505 uint  STDCALL vm_execute( uint main )
506 {
507    pvmobj  pobj;
508    uint i, idmain = 0, result = 0;
509 
510 //   print("Count %i\n", _vm.count );
511    // Проходимся по всем объектам и инициализируем то, что нужно
512    for ( i = _vm.countinit; i < _vm.count; i++ )
513    {
514       pobj = ( pvmobj )PCMD( i );
515 
516       switch ( pobj->type )
517       {
518          case OVM_GLOBAL:
519             global_execute( ( povmglobal )pobj );
520             break;
521          case OVM_TYPE:
522             // Set GHRT_INIT & GHRT_DEINIT flags
523             type_initialize( i );
524             break;
525          case OVM_EXFUNC:
526             exfunc_execute( ( povmfunc )pobj );
527             break;
528          case OVM_IMPORT:
529             import_execute( ( povmimport )pobj );
530             break;
531       }
532       if ( pobj->flag & GHRT_MAYCALL )
533       {
534 //         print("entry 0\n");
535          // Call <entry> functions
536          if ( pobj->flag & GHBC_ENTRY )
537             vm_run( i, NULL, &result, 0x80000 );
538          if ( pobj->flag & GHBC_MAIN )
539             idmain = i;
540 //         print("entry 1\n");
541       }
542    }
543 //   print("OOOPS\n");
544    _vm.countinit = _vm.count;
545    if ( main && idmain )
546    {
547       // Call <main> function
548       vm_run( idmain, NULL, &result, 0x80000 );
549    }
550    return result;
551 }
552 
553 /*-----------------------------------------------------------------------------
554 *
555 * ID: vm_clearname 23.10.06 0.0.A.
556 * 
557 * Summary: This function clear a name of the object
558 *
559 -----------------------------------------------------------------------------*/
560 
561 void   STDCALL vm_clearname( uint id )
562 {
563    phashitem  phi;
564    pvmobj     curobj = 0, pvmo = ( pvmobj )PCMD( id );
565    uint       idnext;
566 
567    if ( !pvmo->name )
568       return;
569    phi = hash_find( &_vm.objname, pvmo->name );
570    idnext = *( puint )( phi + 1 );
571    while ( idnext )
572    {
573       if ( idnext == id )
574       {
575          if ( curobj )
576             curobj->nextname = pvmo->nextname;
577          else
578             *( puint )( phi + 1 ) = pvmo->nextname;
579          break;
580       }
581       curobj = ( pvmobj )PCMD( idnext );
582       idnext = curobj->nextname;
583    }
584    pvmo->flag &= ~GHCOM_NAME;
585    pvmo->name = NULL;
586 }
587 
588 /*-----------------------------------------------------------------------------
589 ** Id: getid F
590 *
591 * Summary: Getting the code of an object by its name. The function returns the 
592            code of an object (function, method, operator, type) by its name 
593            and parameters.
594 *  
595 * Params: name - The name of an object (function, method, operator ). 
596           flags - Flags.$$[getidflags]
597           idparams - The types of the required parameters.
598 * 
599 * Return: The code (identifier) of the found object. The function returns 
600           #b(0) if the such object was not found.
601 *
602 * Define: func uint getid( str name, uint flags, collection idparams )
603 *
604 -----------------------------------------------------------------------------*/
605 
606 uint STDCALL vm_getid( pstr name, uint flags, pcollect colpars )
607 {
608    ubyte  fname[256];
609    uint   off = 0;
610    uint   count;
611    uint   i = 0, k = 0;
612    uint   params[ 32 ];
613    uint   bcode;
614 
615    if ( flags & GETID_METHOD )
616       fname[ off++ ] = '@';
617    if ( flags & GETID_OPERATOR )
618       fname[ off++ ] = '#';
619 
620    mem_copyuntilzero( fname + off, str_ptr( name ));
621 
622    count = collect_count( colpars );
623    while ( i < count )
624    {
625       params[ k++ ] = *( puint )collect_index( colpars, i );
626       params[ k++ ] = flags & GETID_OFTYPE ? *( puint )collect_index( colpars, ++i ) : 0;
627       i++;
628    }
629    
630    bcode = ( uint )vm_find( fname, k >> 1, params );
631    if ( ( uint )bcode < MSGCOUNT )
632       bcode = 0;
633    else 
634       bcode = ((pvmfunc)bcode)->vmo.id;
635    return bcode;
636 }
Редактировать