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
Бесплатные и коммерческие инсталляторы

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