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

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