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 #include "common.h"
   2 #include "bytecode.h"
   3 #include "vm.h"
   4 
   5 
   6 /******************************************************************************
   7 * Summary: This file provides functionality for memory management.
   8 ******************************************************************************/
   9 
  10 
  11 
  12 /*** Locale functions ***/
  13 
  14 uint STDCALL _mem_heapalloc( pvmEngine pThis, uint id )
  15 {
  16    uint   size;
  17    pheap  p_heap;
  18       
  19    size = ( MEM_HEAPSIZE << ( id >> 5 ));
  20    
  21    p_heap = pThis->_memory.heaps + id;
  22    
  23    p_heap->ptr = os_alloc( size + MAX_BYTE * sizeof( uint ));
  24    if ( !p_heap->ptr )
  25       return FALSE;
  26    p_heap->chain = p_heap->ptr;    
  27    p_heap->size = size;
  28    p_heap->remain = size;
  29    p_heap->free = 0;
  30    mem_zeroui( pThis, p_heap->chain, MAX_BYTE );
  31 
  32    return TRUE; 
  33 }
  34 
  35 //--------------------------------------------------------------------------
  36 
  37 uint STDCALL _mem_heapfree( pvmEngine pThis, uint id )
  38 {
  39    pheap  p_heap;
  40            
  41    p_heap = pThis->_memory.heaps + id;
  42    if ( p_heap->ptr )   
  43 //      VirtualFree( p_heap->ptr, 0, MEM_RELEASE );
  44       os_free( p_heap->ptr );
  45    p_heap->ptr = 0;
  46         
  47    return TRUE;
  48 }
  49 
  50 //--------------------------------------------------------------------------
  51 
  52 uint STDCALL _mem_size2sid( pvmEngine pThis, uint size )
  53 {
  54    uint middle, right = 255;
  55    uint left = 0;
  56    
  57    while ( right > left )
  58    {
  59       middle = ( right + left ) >> 1;
  60       if ( size > pThis->_memory.sid[ middle ] )
  61          left = middle + 1;    
  62       else
  63          right = middle;
  64    }
  65    return left;          
  66 }
  67 
  68 /*--------------------------------------------------------------------------
  69 * 
  70 * Public functions
  71 *
  72 */
  73 
  74 /*--------------------------------------------------------------------------
  75 * Description
  76 * Allocate the memory.
  77 *
  78 * Parameters 
  79 * uint size, The required size.
  80 *
  81 * Result 
  82 * uint, The pointer to the memory or 0.
  83 *
  84 */
  85 
  86 pvoid STDCALL mem_alloc( pvmEngine pThis, uint size )
  87 {
  88    uint   sid, ih;
  89    pvoid  result = 0;
  90    pheap  p_heap;
  91    
  92    os_crlsection_enter( &pThis->_crlmem );
  93    if ( size > MEM_EDGE )
  94    {
  95       result = ( pubyte )os_alloc( size + 8 ) + 2;
  96       *(( pubyte )result + 5 ) = MAX_BYTE;
  97       *( puint )result = size;
  98       result = ( pubyte )result + 6;   
  99       goto end;
 100    }
 101    sid = _mem_size2sid( pThis, size );
 102    
 103    ih = pThis->_memory.last;
 104    size = pThis->_memory.sid[ sid ] + 2;
 105     
 106 again:
 107    p_heap = pThis->_memory.heaps + ih;
 108    if ( !p_heap->ptr && !_mem_heapalloc( pThis, ih ))
 109    {
 110       result = 0;
 111       goto end;
 112    }
 113    if ( p_heap->chain[ sid ] )
 114    {
 115       p_heap->free -= size;
 116       result = ( pvoid )p_heap->chain[ sid ];
 117       p_heap->chain[ sid ] = *( puint )result; 
 118    }
 119    else
 120    {
 121       if ( size <= p_heap->remain )
 122       {
 123          result = ( pubyte )p_heap->ptr + MAX_BYTE * sizeof( uint ) + 
 124                   p_heap->size - p_heap->remain;
 125          *(( pubyte )result)++ = ( byte )ih;
 126          *(( pubyte )result)++ = ( byte )sid;
 127          p_heap->remain -= size;
 128       }
 129       else
 130       {
 131          if ( pThis->_memory.last )
 132          {
 133             pThis->_memory.last = 0;
 134             ih = 0;   
 135          }
 136          else
 137             ih++;
 138          goto again;
 139       } 
 140    }
 141    pThis->_memory.last = ih;
 142 
 143 end:
 144    os_crlsection_leave( &pThis->_crlmem );
 145    mem_zero( pThis, result, size );
 146    return result;
 147 }
 148 
 149 //--------------------------------------------------------------------------
 150 
 151 pvoid  STDCALL mem_copy( pvmEngine pThis, pvoid dest, pvoid src, uint len )
 152 {
 153    puint psrc = ( puint )src;
 154    puint pdest = ( puint )dest;
 155    uint  ilen = len >> 2;
 156 
 157    while ( ilen-- ) 
 158       *pdest++ = *psrc++;
 159    
 160    len &= 0x3;
 161    while ( len-- )
 162       *((pubyte)pdest)++ = *((pubyte)psrc)++;
 163 
 164    return dest;
 165 }
 166 
 167 //--------------------------------------------------------------------------
 168 
 169 uint STDCALL mem_deinit( pvmEngine pThis )
 170 {
 171    uint i;
 172 
 173    for ( i = 0; i <= MAX_BYTE; i++ )
 174       _mem_heapfree( pThis, i );
 175       
 176    os_free( pThis->_memory.sid );
 177    os_free( pThis->_memory.heaps );
 178 
 179    os_crlsection_delete( &pThis->_crlmem );
 180  
 181    return TRUE;
 182 }
 183 
 184 //--------------------------------------------------------------------------
 185 
 186 uint  STDCALL mem_free( pvmEngine pThis, pvoid ptr )
 187 {
 188    pubyte  p_id;
 189    uint   sid;
 190    pheap  p_heap;
 191 
 192    if ( !ptr ) return TRUE;
 193 
 194    os_crlsection_enter( &pThis->_crlmem );
 195 
 196    sid = *(( pubyte )ptr - 1 );
 197    p_id = ( pubyte )ptr - 2;
 198    
 199    if ( sid == MAX_BYTE )
 200    {
 201       os_free( ( pubyte )ptr - 8 );
 202       goto end;
 203    }  
 204    p_heap = pThis->_memory.heaps + *p_id; 
 205    *( puint )ptr = p_heap->chain[ sid ];
 206    p_heap->chain[ sid ] = ( uint )ptr;
 207    
 208    p_heap->free += pThis->_memory.sid[ sid ] + 2;
 209    
 210    if ( p_heap->free + p_heap->remain == p_heap->size )
 211       _mem_heapfree( pThis, *p_id );
 212    
 213 end:
 214    os_crlsection_leave( &pThis->_crlmem );
 215 
 216    return TRUE;        
 217 }
 218 
 219 //--------------------------------------------------------------------------
 220 
 221 uint  STDCALL mem_getsize( pvmEngine pThis, pvoid ptr )
 222 {
 223    uint  sid;
 224 
 225    if ((  sid = *((pubyte)ptr - 1 )) == MAX_BYTE )
 226       return *( puint )((pubyte)ptr - 8 );
 227    return pThis->_memory.sid[ sid ];
 228 }
 229 
 230 //--------------------------------------------------------------------------
 231 
 232 uint STDCALL mem_init( pvmEngine pThis )
 233 {
 234    uint  i, size, step = 8;
 235 
 236    pThis->_memory.sid = os_alloc(( MAX_BYTE + 1 ) * sizeof( uint ));
 237    pThis->_memory.sid[ 0 ] = step;
 238 
 239    for ( i = 1; i < MAX_BYTE - 1; i++ )
 240    {
 241       if ( !( i & 0xF )) 
 242          step <<= 1;
 243       pThis->_memory.sid[ i ] = pThis->_memory.sid[ i - 1 ] + step;   
 244    }
 245    pThis->_memory.sid[ MAX_BYTE ] = MAX_UINT;
 246  
 247    pThis->_memory.heaps = os_alloc( size = (MAX_BYTE + 1) * sizeof( heap ));
 248    mem_zero( pThis, pThis->_memory.heaps, size );
 249 
 250    os_crlsection_init( &pThis->_crlmem );
 251    pThis->_memory.last = 0;
 252 
 253    return TRUE;   
 254 }
 255 
 256 //--------------------------------------------------------------------------
 257 
 258 uint STDCALL mem_len( pvmEngine pThis, pvoid data )
 259 {
 260   pubyte temp = ( pubyte )data;
 261 
 262   while ( *temp++ );
 263 
 264   return ( uint )( temp - ( pubyte )data - 1 );
 265 }
 266 
 267 //--------------------------------------------------------------------------
 268 
 269 //--------------------------------------------------------------------------
 270 
 271 void  STDCALL mem_move( pvmEngine pThis, pvoid dest, pvoid src, uint len )
 272 {
 273    puint  psrc;
 274    puint  pdest;
 275    uint   ilen;
 276 
 277    if ( ( pubyte )dest <= ( pubyte )src || 
 278          ( pubyte )dest >= ( pubyte )src + len ) 
 279       mem_copy( pThis, dest, src, len );
 280    else 
 281    {
 282       ilen = len >> 2;
 283       // области памяти пересекаются и надо копировать с конца
 284       pdest = ( puint )( ( pubyte )dest + len - sizeof( uint ));
 285       psrc = ( puint )(( pubyte )src + len - sizeof( uint ));
 286       while ( ilen-- ) 
 287          *pdest-- = *psrc--;
 288 
 289       len &= 0x3;
 290       while ( len-- )
 291          *( ( pubyte )dest + len ) = *( ( pubyte )src + len );
 292    }
 293 }
 294 
 295 //--------------------------------------------------------------------------
 296 
 297 pvoid STDCALL mem_zero( pvmEngine pThis, pvoid dest, uint len )
 298 {
 299    puint  p_dest = ( puint )dest;
 300    uint   ilen = len >> 2;
 301 
 302    while ( ilen-- ) 
 303       *p_dest++ = 0;
 304    
 305    len &= 0x3;
 306    while ( len-- )
 307       *((pubyte)p_dest)++ = 0;
 308 
 309    return dest;
 310 }
 311 
 312 //--------------------------------------------------------------------------
 313 
 314 int  STDCALL mem_cmp( pvmEngine pThis, pvoid dest, pvoid src, uint len )
 315 {
 316    puint dsrc = ( puint )src;
 317    puint ddest = ( puint )dest;
 318    uint  ilen = len >> 2;
 319    int   i;
 320 
 321    while ( ilen-- )
 322       if ( *ddest++ != *dsrc++ )
 323       {
 324          ddest--;
 325          dsrc--;
 326          for ( i = 0; i < 4; i++ )
 327          {
 328             if ( *((pubyte)ddest) > *((pubyte)dsrc) )
 329                return 1;
 330             if ( *((pubyte)ddest)++ < *((pubyte)dsrc)++ )
 331                return -1;
 332          }
 333       }
 334 
 335    len &= 0x3;
 336    while ( len-- )
 337    {
 338       if ( *((pubyte)ddest) > *((pubyte)dsrc) )
 339          return 1;
 340       if ( *((pubyte)ddest)++ < *((pubyte)dsrc)++ )
 341          return -1;
 342    }
 343 
 344    return 0;
 345 }
 346 
 347 
 348 //--------------------------------------------------------------------------
 349 
 350 void  STDCALL mem_zeroui( pvmEngine pThis, puint dest, uint len )
 351 {
 352    while ( len-- ) 
 353       *dest++ = 0;
 354 }
 355 
 356 
 357 
 358 //--------------------------------------------------------------------------
 359 
 360 uint  STDCALL mem_copyuntilzero( pvmEngine pThis, pubyte dest, pubyte src  )
 361 {
 362   pubyte temp = dest;
 363 
 364   while ( *src )
 365      *temp++ = *src++;
 366   *temp = 0;
 367   return ( uint )( temp - dest + 1 );
 368 }
 369 
 370 
 371 /******************************************************************************
 372 *
 373 * Summary: This file provides functionality for 'buf' type.
 374 *
 375 ******************************************************************************/
 376 
 377 
 378 pbuf  STDCALL buf_alloc( pvmEngine pThis, pbuf pb, uint size )
 379 {
 380    mem_free( pThis, pb->data );
 381 
 382    pb->data = mem_alloc( pThis, size );
 383    pb->size = mem_getsize( pThis, pb->data );
 384    pb->use = 0;
 385 
 386    return pb;
 387 }
 388 
 389 
 390 /*-----------------------------------------------------------------------------
 391 *
 392 * ID: buf_appendch 19.10.06 0.0.A.
 393 * 
 394 * Summary: Append a ubyte to buf
 395 *  
 396 -----------------------------------------------------------------------------*/
 397 
 398 pbuf STDCALL buf_append( pvmEngine pThis, pbuf pb, pubyte src, uint size )
 399 {
 400     buf_expand( pThis, pb, size + 1 );
 401     mem_copy( pThis, pb->data + pb->use, src, size );
 402     pb->use += size;
 403     
 404     return pb;
 405 }
 406 
 407 pbuf   STDCALL buf_appendch( pvmEngine pThis, pbuf pb, ubyte val )
 408 {
 409    buf_expand( pThis, pb, 1 );
 410    *( pb->data + pb->use ) = val;
 411    pb->use++;
 412    return pb;
 413 }
 414 
 415 pbuf STDCALL buf_appenduint( pvmEngine pThis, pbuf pb, uint val )
 416 {
 417    buf_expand( pThis, pb, sizeof( uint ));
 418    *( pint )( pb->data + pb->use ) = val;
 419    pb->use += sizeof( uint );
 420    
 421    return pb;
 422 }
 423 
 424 
 425 pbuf STDCALL buf_appendushort( pvmEngine pThis, pbuf pb, ushort val )
 426 {
 427    buf_expand( pThis, pb, sizeof( ushort ));
 428    *( pushort )( pb->data + pb->use ) = val;
 429    pb->use += sizeof( ushort );
 430    
 431    return pb;
 432 }
 433 
 434 pbuf  STDCALL buf_copy( pvmEngine pThis, pbuf pb, pubyte src, uint size )
 435 {
 436    pb->use = 0;
 437    buf_reserve( pThis, pb, size + 1 );
 438    mem_copy( pThis, pb->data, src, size );
 439    pb->use = size;
 440    
 441    return pb;
 442 }
 443 
 444 
 445 //--------------------------------------------------------------------------
 446 
 447 pbuf   STDCALL buf_copyzero( pvmEngine pThis, pbuf pb, pubyte src )
 448 {
 449    return buf_copy( pThis, pb, src, mem_len( pThis, src ) + 1 );
 450 }
 451 
 452 //--------------------------------------------------------------------------
 453 
 454 void STDCALL buf_delete( pvmEngine pThis, pbuf pb )
 455 {
 456    mem_free( pThis, pb->data );
 457    pb->data = NULL;
 458 }
 459 
 460 //--------------------------------------------------------------------------
 461 
 462 pbuf STDCALL buf_init( pvmEngine pThis, pbuf pb )
 463 {
 464    mem_zero( pThis, pb, sizeof( buf ));
 465    return pb;
 466 }
 467 
 468 //--------------------------------------------------------------------------
 469 
 470 pbuf  STDCALL buf_insert( pvmEngine pThis, pbuf pb, uint off, pubyte data, uint size )
 471 {
 472    if ( off > pb->use )
 473       off = pb->use;
 474 
 475    buf_expand( pThis, pb, size );
 476    mem_move( pThis, pb->data + off + size, pb->data + off, pb->use - off );
 477    if ( data )
 478       mem_copy( pThis, pb->data + off, data, size );
 479    pb->use += size;
 480 
 481    return pb;
 482 }
 483 
 484 uint STDCALL buf_len( pvmEngine pThis, pbuf pb )
 485 {
 486    return pb->use;
 487 }
 488 
 489 pubyte STDCALL buf_ptr( pvmEngine pThis, pbuf pb )
 490 {
 491    return pb->data;
 492 }
 493 
 494 //--------------------------------------------------------------------------
 495 // size - the additional size
 496 
 497 pbuf  STDCALL buf_expand( pvmEngine pThis, pbuf pb, uint size )
 498 {
 499    uint   tmp;
 500    pubyte old = pb->data;
 501    uint   use = pb->use;
 502 
 503    size += use; // only size is additional size
 504    if ( size <= pb->size )
 505       return pb;
 506 
 507    if ( !pb->step )
 508       pb->step = max( size/2, 32 );
 509    else
 510       if ( pb->step < pb->size / 2 ) 
 511          pb->step = pb->size / 2;
 512    
 513    tmp = pb->size + pb->step;
 514    if ( size < tmp )
 515       size = tmp;
 516    pb->data = 0;
 517    buf_alloc( pThis, pb, size );
 518    if ( old )
 519    {
 520       mem_copy( pThis, pb->data, old, use );
 521       pb->use = use;
 522       mem_free( pThis, old );
 523    }
 524 
 525    return pb;
 526 }
 527 
 528 
 529 //--------------------------------------------------------------------------
 530 // size - the full required size
 531 
 532 pbuf  STDCALL buf_reserve( pvmEngine pThis, pbuf pb, uint size )
 533 {
 534    if ( size <= pb->size )
 535       return pb;
 536 
 537    return buf_expand( pThis, pb, size - pb->use );
 538 }
 539 
 540 /*-----------------------------------------------------------------------------
 541 *
 542 * ID: buf_setlen 19.10.06 0.0.A.
 543 * 
 544 * Summary: Set the length of the buffer
 545 *
 546 -----------------------------------------------------------------------------*/
 547 
 548 pbuf   STDCALL buf_setlen( pvmEngine pThis, pbuf pb, uint len )
 549 {
 550    pb->use = len > pb->size ? pb->size : len ;
 551 
 552    return pb;
 553 }
 554 
 555 
 556 
 557 /******************************************************************************
 558 *
 559 *
 560 ******************************************************************************/
 561 
 562 
 563 //--------------------------------------------------------------------------
 564 // Возвращается указатель на добавленный элемент
 565 
 566 pvoid  STDCALL arr_append( pvmEngine pThis, parr pa )
 567 {
 568    arr_reserve( pThis, pa, 1 );
 569 
 570    mem_zero( pThis, buf_ptr( pThis, &pa->data ) + pa->data.use, pa->isize );
 571    pa->data.use += pa->isize;
 572 
 573    return buf_ptr( pThis, &pa->data ) + pa->data.use - pa->isize;
 574 }
 575 
 576 //--------------------------------------------------------------------------
 577 
 578 uint  STDCALL arr_appenditems( pvmEngine pThis, parr pa, uint count )
 579 {
 580    uint    size = count * pa->isize;
 581 
 582    arr_reserve( pThis, pa, count );
 583 
 584    mem_zero( pThis, buf_ptr( pThis, &pa->data ) + pa->data.use, size );
 585    pa->data.use += size;
 586 
 587 //   printf("Append %i size=%i\n", pa->data.use, pa->data.size );
 588    return pa->data.use / pa->isize;
 589 }
 590 
 591 //--------------------------------------------------------------------------
 592 
 593 void  STDCALL arr_appendnum( pvmEngine pThis, parr pa, uint val )
 594 {
 595    *( puint )arr_append( pThis, pa ) = val;
 596 }
 597 
 598 //--------------------------------------------------------------------------
 599 
 600 
 601 //--------------------------------------------------------------------------
 602 
 603 uint  STDCALL arr_count( pvmEngine pThis, parr pa )
 604 {
 605    return buf_len( pThis, &pa->data ) / pa->isize;
 606 }
 607 
 608 //--------------------------------------------------------------------------
 609 
 610 void  STDCALL arr_delete( pvmEngine pThis, parr pa )
 611 {
 612    puint ptr, end;
 613 
 614    if ( pa->isobj )
 615    {
 616       ptr = ( puint )buf_ptr( pThis, &pa->data );
 617       end = ( puint )(( pubyte )ptr + buf_len( pThis, &pa->data ));
 618       while ( ptr < end )
 619       {
 620          mem_free( pThis, ( pvoid )*ptr );
 621          ptr++;
 622       }
 623    }
 624    buf_delete( pThis, &pa->data );
 625 }
 626 
 627 //--------------------------------------------------------------------------
 628 
 629 uint  STDCALL arr_getuint( pvmEngine pThis, parr pa, uint num )
 630 {
 631    return *( puint )( buf_ptr( pThis, &pa->data ) + num * pa->isize );
 632 }
 633 
 634 //--------------------------------------------------------------------------
 635 
 636 void  STDCALL arr_init( pvmEngine pThis, parr pa, uint size )
 637 {
 638    buf_init( pThis, &pa->data );
 639    
 640    pa->isobj = 0;
 641    if ( !size )
 642    {
 643       size = sizeof( uint );
 644       pa->isobj = 1;
 645    }
 646    pa->isize = size;
 647 }
 648 
 649 //--------------------------------------------------------------------------
 650 
 651 pvoid  STDCALL arr_ptr( pvmEngine pThis, parr pa, uint num )
 652 {
 653    return buf_ptr( pThis, &pa->data ) + num * pa->isize;
 654 }
 655 
 656 
 657 //--------------------------------------------------------------------------
 658 // count - количество резервируемых элементов
 659 
 660 void  STDCALL arr_reserve( pvmEngine pThis, parr pa, uint count )
 661 {
 662    buf_expand( pThis, &pa->data, count * pa->isize );
 663 }
 664 
 665 //--------------------------------------------------------------------------
 666 
 667 void   STDCALL arr_setuint( pvmEngine pThis, parr pa, uint num, uint value )
 668 {
 669    *( puint )( buf_ptr( pThis, &pa->data ) + num * pa->isize ) = value;
 670 }
 671 
 672 //--------------------------------------------------------------------------
 673 // count - количество резервируемых элементов
 674 
 675 void  STDCALL arr_step( pvmEngine pThis, parr pa, uint count )
 676 {
 677    pa->data.step = count * pa->isize;
 678 }
 679 
 680 
 681 /******************************************************************************
 682 * Summary: This file provides functionality for 'str' type.
 683 *
 684 ******************************************************************************/
 685 
 686 
 687 /*-----------------------------------------------------------------------------
 688 *
 689 * ID: str_copy 19.10.06 0.0.A.
 690 * 
 691 * Summary: Copy the string
 692 *  
 693 -----------------------------------------------------------------------------*/
 694 
 695 pstr  STDCALL str_copy( pvmEngine pThis, pstr dest, pstr src )
 696 {
 697    return buf_copy( pThis, ( pbuf )dest, str_ptr( src ), src->use );
 698 }
 699 
 700 //--------------------------------------------------------------------------
 701 
 702 pstr   STDCALL str_copyzero( pvmEngine pThis, pstr ps, pubyte src )
 703 {
 704    ps->use--;
 705    buf_copyzero( pThis, ps, src );
 706    return ps;
 707 }
 708 
 709 
 710 pstr STDCALL str_init( pvmEngine pThis, pstr ps )
 711 {
 712    mem_zero( pThis, ps, sizeof( str ));
 713    
 714    buf_alloc( pThis, ps, 32 );
 715    ps->data[0] = 0;
 716    ps->use = 1;
 717 //   print("String Init %x\n", ps );
 718    return ps;
 719 }
 720 
 721 
 722 uint  STDCALL str_len( pvmEngine pThis, pstr ps )
 723 {
 724    return ps->use - 1;
 725 }
 726 
 727 
 728 
 729 /*-----------------------------------------------------------------------------
 730 *
 731 * ID: str_setlen 19.10.06 0.0.A.
 732 * 
 733 * Summary: Reserve string space
 734 *  
 735 * Params: len - additional required size
 736 *
 737 -----------------------------------------------------------------------------*/
 738 
 739 pstr   STDCALL str_setlen( pvmEngine pThis, pstr ps, uint len )
 740 {
 741    if ( len >= ps->size )
 742       len = 0;
 743 
 744    ps->use = len + 1;
 745    ps->data[ len ] = 0;
 746 
 747    return ps;
 748 }
 749 
 750 /*-----------------------------------------------------------------------------
 751 *
 752 * ID: str_new 19.10.06 0.0.A.
 753 * 
 754 * Summary: Create str object.
 755 *  
 756 -----------------------------------------------------------------------------*/
 757 
 758 pstr  STDCALL str_new( pvmEngine pThis, pubyte ptr )
 759 {
 760    pstr  ret = mem_alloc( pThis, sizeof( str ));
 761 
 762    str_init( pThis, ret );
 763    if ( ptr )
 764       str_copyzero( pThis, ret, ptr );
 765 
 766    return ret;
 767 }
 768 
 769 
 770 
 771 /******************************************************************************
 772 *
 773 ******************************************************************************/
 774 
 775 
 776 //--------------------------------------------------------------------------
 777 
 778 puint STDCALL collect_add( pvmEngine pThis, pcollect pclt, puint input, uint type )
 779 {
 780 //   uint value;
 781 
 782    pclt->count++;
 783    buf_appenduint( pThis, ( pbuf )pclt, type );
 784    if ( (( povmtype )PCMD( type ))->stsize == 2 )
 785    {
 786       pclt->flag |= 0x01;
 787       buf_append( pThis, ( pbuf )pclt, ( pubyte )input, sizeof( long64 ));
 788       return input + 2;
 789    }
 790    else
 791    {
 792       buf_appenduint( pThis, ( pbuf )pclt, *input );
 793    }
 794    return  input + 1;
 795 }
 796 
 797 pubyte    STDCALL collect_addptr( pvmEngine pThis, pcollect pclt, pubyte ptr )
 798 {
 799    pstr  ps = str_new( pThis, ptr );
 800 
 801    collect_add( pThis, pclt, ( puint )&ps, TStr );
 802    return ptr + mem_len( pThis, ptr ) + 1;
 803 }
 804 
 805 pubyte  STDCALL collect_index( pvmEngine pThis, pcollect pclt, uint index )
 806 {
 807    uint  i;
 808    uint  off = 0;
 809 
 810    if ( index >= pclt->count )
 811       return 0;
 812    
 813    if ( pclt->flag & 0x01 )
 814    {
 815       for( i = 0; i < index; i++ )
 816       {
 817          off += sizeof( uint ) + ((( povmtype )PCMD( *( puint )( 
 818                    buf_ptr( pThis, ( pbuf )pclt ) + off ) ))->stsize << 2 );
 819       }
 820    }
 821    else
 822       off = ( index << 3 );
 823    return buf_ptr( pThis, ( pbuf )pclt ) + off + sizeof( uint );
 824 }
 825 
 826 uint   STDCALL  collect_gettype( pvmEngine pThis, pcollect pclt, uint index )
 827 {
 828    if ( index < pclt->count ) 
 829       return *(( puint )collect_index( pThis, pclt, index ) - 1 );
 830    return 0;
 831 }
 832 
 833 
 834 uint  STDCALL collect_count( pvmEngine pThis, pcollect pclt )
 835 {
 836    return pclt->count;
 837 }
 838 
 839 void  STDCALL collect_delete( pvmEngine pThis, pcollect pclt )
 840 {
 841 // !!! сделать collect_delete() с учетом поля owner. Добавить поле.
 842 }
 843 
 844 
 845 /******************************************************************************
 846 *
 847 *
 848 ******************************************************************************/
 849 
 850 
 851 void  STDCALL hash_delete( pvmEngine pThis, phash ph )
 852 {
 853    arr_delete( pThis, &ph->values );
 854    arr_delete( pThis, &ph->names );
 855 }
 856 
 857 //--------------------------------------------------------------------------
 858 
 859 phashitem  STDCALL _hash_find( pvmEngine pThis, phash ph, pubyte name, uint create )
 860 {
 861    pubyte  ptr = name;
 862    ushort  val = 0;
 863    uint    len = 0;   
 864    ubyte   shift = 0;
 865    ushort  nameoff;
 866    phashitem  phi = 0, prev = 0;
 867 
 868    // Вычисляем хэш-значение строки
 869    while ( *ptr )
 870    {
 871          val += (( ushort )*ptr++ ) << shift;
 872       if ( ++shift > 7 )
 873          shift = 0;
 874       len++;
 875    }
 876 // получаем номер в хэш-таблице
 877    val &= HASH_SIZE - 1;
 878    phi = prev = ( phashitem )arr_getuint( pThis, &ph->values, val );
 879    nameoff = sizeof( hashitem ) + ph->isize;
 880    while ( phi )
 881    {
 882       if ( len == phi->len && !(/* ph->ignore ? 
 883                   mem_cmpign( pThis, name, ( pubyte )phi + nameoff, len ) : */
 884                 mem_cmp( pThis, name, ( pubyte )phi + nameoff, len )))
 885          // нашли совпадение
 886          return phi;
 887       phi = ( phashitem )phi->next;
 888    }
 889    if ( create )
 890    {
 891       // Будем добавлять элемент в таблицу имен
 892       phi = ( phashitem )mem_alloc( pThis, nameoff + len + 1 );
 893       phi->len = ( ushort )len;
 894       phi->next = ( pvoid )prev;
 895       phi->id = arr_count( pThis, &ph->names );
 896       mem_zero( pThis, ( pubyte )phi + sizeof( hashitem ), ph->isize );
 897       mem_copy( pThis, ( pubyte )phi + nameoff, name, len + 1 );
 898       arr_appendnum( pThis, &ph->names, ( uint )phi );
 899       arr_setuint( pThis, &ph->values, val, ( uint )phi );
 900    }
 901    return phi;
 902 }
 903 
 904 //--------------------------------------------------------------------------
 905 
 906 phashitem  STDCALL hash_find( pvmEngine pThis, phash ph, pubyte name )
 907 {
 908    return _hash_find( pThis, ph, name, 0 );
 909 }
 910 
 911 //--------------------------------------------------------------------------
 912 
 913 void  STDCALL hash_init( pvmEngine pThis, phash ph, uint isize )
 914 {
 915    arr_init( pThis, &ph->values, sizeof( uint ));
 916    arr_appenditems( pThis, &ph->values, HASH_SIZE );
 917 
 918    arr_init( pThis, &ph->names, 0 );
 919    arr_step( pThis, &ph->names, 512 );
 920    ph->isize = isize;
 921    ph->ignore = 0;
 922 }
 923 
 924 //--------------------------------------------------------------------------
 925 
 926 phashitem  STDCALL hash_create( pvmEngine pThis, phash ph, pubyte name )
 927 {
 928    return _hash_find( pThis, ph, name, 1 );
 929 }
 930 
 931 //--------------------------------------------------------------------------
 932 
 933 
 934 
 935 /******************************************************************************
 936 *
 937 * Summary: This file provides calculating CRC32.
 938 *
 939 ******************************************************************************/
 940 
 941 
 942 //--------------------------------------------------------------------------
 943 
 944 void STDCALL crc_init( pvmEngine pThis )
 945 {
 946    uint  reg, polinom, i, ib;
 947 
 948    polinom = 0xEDB88320;
 949    pThis->_crctbl[ 0 ] = 0;
 950 
 951    for ( i = 1; i < 256; i++ )
 952    {
 953       reg = 0;
 954       for ( ib = i | 256; ib != 1; ib >>= 1 )
 955       {
 956          reg = ( reg & 1 ? (reg >> 1) ^ polinom : reg >> 1 );
 957          if ( ib & 1 )
 958             reg ^= polinom;
 959       }
 960       pThis->_crctbl[ i ] = reg;
 961    }
 962 }
 963 
 964 //--------------------------------------------------------------------------
 965 // seed must be 0xFFFFFFFF in the first calling
 966 
 967 uint STDCALL crc( pvmEngine pThis, pubyte data, uint size, uint seed )
 968 {
 969    while ( size-- )
 970       seed = pThis->_crctbl[((ushort)seed ^ ( *data++ )) & 0xFF ] ^ ( seed >> 8 );
 971 
 972    return seed;
 973 }
 974 
 975 //--------------------------------------------------------------------------
 976 
 977 
 978 /*-----------------------------------------------------------------------------
 979 *
 980 * ID: file2buf 23.10.06 0.0.A.
 981 * 
 982 * Summary: Read file to buf. Result must be destroy later. name is converted 
 983   into the full name.
 984 *
 985 -----------------------------------------------------------------------------*/
 986 
 987 pbuf STDCALL file2buf( pvmEngine pThis, pstr name, pbuf ret, uint pos )
 988 {
 989    str       filename;
 990    uint      search = 0;
 991    uint      handle, size;
 992 //   parrdata  pad;
 993 
 994    str_init( pThis, &filename );
 995    os_filefullname( pThis, name, &filename );
 996 
 997    handle = os_fileopen( &filename, FOP_READONLY );
 998    if ( !handle )
 999    {
1000       longjmp( pThis->stack_state, -1 );//msg( pThis, MFileopen | MSG_STR | MSG_EXIT | MSG_POS, &filename, pos );
1001    }
1002    size = ( uint )os_filesize( handle );
1003    buf_reserve( pThis, ret, size );
1004 
1005    if ( size && !os_fileread( handle, buf_ptr( pThis, ret ), size ))
1006       longjmp( pThis->stack_state, -1 );//msg( pThis, MFileread | MSG_STR | MSG_EXIT | MSG_POS, &filename, pos );
1007 
1008    buf_setlen( pThis, ret, size );
1009    os_fileclose( handle );
1010 
1011    str_copy( pThis, name, &filename );
1012 
1013    str_delete( pThis, &filename );
1014 
1015    return ret;
1016 }
1017 
1018 uint  STDCALL buf2file( pvmEngine pThis, pstr name, pbuf out )
1019 {
1020    str       filename;
1021    uint      handle;
1022 
1023    str_init( pThis, &filename );
1024    str_reserve( pThis, &filename, 512 );
1025    str_reserve( pThis, &filename, 512 );
1026    os_filefullname( pThis, name, &filename );
1027 
1028    handle = os_fileopen( &filename, FOP_CREATE );
1029    if ( !handle )
1030      longjmp( pThis->stack_state, -1 );//msg( pThis, MFileopen | MSG_STR | MSG_EXIT, &filename );
1031 
1032    if ( !os_filewrite( handle, buf_ptr( pThis, out ), buf_len( pThis, out ) ))
1033       longjmp( pThis->stack_state, -1 );//msg( pThis, MFileread | MSG_STR | MSG_EXIT, &filename );
1034 
1035    os_fileclose( handle );
1036 
1037    str_copy( pThis, name, &filename );
1038    str_delete( pThis, &filename );
1039 
1040    return 1;
1041 }
1042 
1043 
1044 /*-----------------------------------------------------------------------------
1045 * Summary: Close the file
1046 -----------------------------------------------------------------------------*/
1047 
1048 uint     STDCALL os_fileclose( uint handle )
1049 {
1050    return CloseHandle(( pvoid )handle );
1051 }
1052 
1053 /*-----------------------------------------------------------------------------
1054 * Summary: Get the full name of the file
1055 -----------------------------------------------------------------------------*/
1056 
1057 pstr  STDCALL os_filefullname( pvmEngine pThis, pstr filename, pstr result )
1058 {
1059    uint   len;
1060    pubyte ptr;
1061 
1062    str_reserve( pThis, result, 512 );
1063    len = GetFullPathName( str_ptr( filename ), 512, str_ptr( result ), &ptr );
1064    str_setlen( pThis, result, len );
1065    return result;
1066 }
1067 
1068 
1069 uint  STDCALL os_fileopen( pstr name, uint flag )
1070 {
1071    uint ret;
1072 
1073    ret = ( uint )CreateFile( str_ptr( name ), ( flag & FOP_READONLY ? GENERIC_READ : 
1074             GENERIC_READ | GENERIC_WRITE ), ( flag & FOP_EXCLUSIVE ? 0 : 
1075             FILE_SHARE_READ | FILE_SHARE_WRITE ), NULL, 
1076            ( flag & FOP_CREATE ? CREATE_ALWAYS :
1077               ( flag & FOP_IFCREATE ? OPEN_ALWAYS : OPEN_EXISTING )),
1078            0, NULL ); 
1079    return ret == ( uint )INVALID_HANDLE_VALUE ? 0 : ret ;
1080 }
1081 
1082 
1083 uint   STDCALL os_fileread( uint handle, pubyte data, uint size )
1084 {
1085    uint  read;
1086 
1087    if ( !ReadFile( (pvoid)handle, data, size, &read, NULL ) || read != size ) 
1088       return FALSE;
1089    return read;
1090 }
1091 
1092 ulong64  STDCALL os_filesize( uint handle )
1093 {
1094    LARGE_INTEGER  li;
1095 
1096    li.LowPart = GetFileSize( ( pvoid )handle, &li.HighPart ); 
1097  
1098    if ( li.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR )
1099       return -1L;
1100 
1101    return li.QuadPart;
1102 }
1103 
1104 //--------------------------------------------------------------------------
1105 
1106 uint   STDCALL os_filewrite( uint handle, pubyte data, uint size )
1107 {
1108    uint  write;
1109 
1110    if ( !WriteFile( ( pvoid )handle, data, size, &write, NULL ) || write != size ) 
1111       return FALSE;
1112    return write;
1113 }
1114 
1115 
1116