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

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.

source\src\vm\vmrun.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: vmrun 26.12.06 0.0.A.
  11 *
  12 * Author: Alexey Krivonogov ( gentee )
  13 * Contributors: santy
  14 *
  15 * Summary: 
  16 * 
  17 ******************************************************************************/
  18 
  19 #include "vmtype.h"
  20 #include "vmload.h"
  21 #include "../common/collection.h"
  22 #include "../genteeapi/gentee.h"
  23 //#include "../bytecode/bytecode.h"
  24 
  25 //--------------------------------------------------------------------------
  26 
  27 void STDCALL pseudo_i( pstackpos curpos )
  28 {
  29    uint       cmd = *curpos->cmd;
  30    pint       pop1 = curpos->top - 1;
  31    pint       pop2 = curpos->top - 2;
  32    int        val1 = *pop1;
  33    int        val2 = *pop2;
  34 
  35    switch ( cmd )
  36    {
  37       case CMulII:   *pop2 *= val1; break; // Replaced with CMulUIUI
  38       case CDivII:   *pop2 /= val1; break;
  39       case CModII:   *pop2 %= val1; break;
  40       case CLeftII:  *pop2 <<= val1; break;  // Replaced with CLeftUIUI
  41       case CRightII: *pop2 >>= val1; break;
  42       case CSignI:   *pop1 = -val1; break;
  43       case CLessII:  *pop2 = val2 < val1 ? 1 : 0; break;
  44       case CGreaterII:  *pop2 = val2 > val1 ? 1 : 0; break;
  45       case CMulI:   *( pint )val2 *= val1; goto seti; // Replaced with CMulUI
  46       case CDivI:   *( pint )val2 /= val1; goto seti;
  47       case CModI:   *( pint )val2 %= val1; goto seti;
  48       case CLeftI:  *( pint )val2 <<= val1; goto seti;  // Replaced with CLeftUI
  49       case CRightI: *( pint )val2 >>= val1; goto seti;
  50       case CMulB:   *( pchar )val2 *= val1; goto setb;
  51       case CDivB:   *( pchar )val2 /= val1; goto setb;
  52       case CModB:   *( pchar )val2 %= val1; goto setb;
  53       case CLeftB:  *( pchar )val2 <<= val1; goto setb;
  54       case CRightB: *( pchar )val2 >>= val1; goto setb;
  55       case CMulS:   *( pshort )val2 *= val1; goto sets;
  56       case CDivS:   *( pshort )val2 /= val1; goto sets;
  57       case CModS:   *( pshort )val2 %= val1; goto sets;
  58       case CLeftS:  *( pshort )val2 <<= val1; goto sets;
  59       case CRightS: *( pshort )val2 >>= val1; goto sets;
  60       case Cd2f: *( float* )pop2 = (float)*( double * )pop2; break;
  61       case Cd2i: *( int* )pop2 = (int)*( double * )pop2; break;
  62       case Cd2l: *( long64* )pop2 = ( long64 )*( double * )pop2; break;
  63       case Cf2d: *( double* )pop1 = ( double )*( float * )pop1; break;
  64       case Cf2i: *( int* )pop1 = ( int )*( float * )pop1; break;
  65       case Cf2l: *( long64* )pop1 = ( long64 )*( float * )pop1; break;
  66       case Ci2d: *( double* )pop1 = ( double )*( int * )pop1; break;
  67       case Ci2f: *( float* )pop1 = (float)*( int * )pop1; break;
  68       case Ci2l: *( long64* )pop1 = ( long64 )*( int * )pop1; break;
  69       case Cl2d: *( double* )pop2 = ( double )*( long64 * )pop2; break;
  70       case Cl2f: *( float* )pop2 = (float)*( long64 * )pop2; break;
  71       case Cl2i: *( int* )pop2 = ( int )*( long64 * )pop2; break;
  72       case Cui2d: *( double* )pop1 = ( double )*( uint * )pop1; break;
  73       case Cui2f: *( float* )pop1 = (float)*( uint * )pop1; break;
  74       case Cui2l: *( long64* )pop1 = ( long64 )*( uint * )pop1; break;
  75    }
  76    return;
  77 seti:
  78    *pop2 = *( pint )val2;
  79    return;
  80 setb:
  81    *pop2 = *( pchar )val2;
  82    return;
  83 sets:
  84    *pop2 = *( pshort )val2;
  85 }
  86 
  87 //--------------------------------------------------------------------------
  88 
  89 void STDCALL pseudo_ul( pstackpos curpos )
  90 {
  91    uint          cmd = *curpos->cmd;
  92    pulong64      pop1 = ( pulong64 )curpos->top - 1;
  93    pulong64      pop2 = ( pulong64 )curpos->top - 2;
  94    ulong64       val1 = *pop1;
  95    ulong64       val2 = *pop2;
  96 
  97    switch ( cmd )
  98    {
  99       case CAddULUL: *pop2 += val1; break;
 100       case CSubULUL: *pop2 -= val1; break;
 101       case CMulULUL: *pop2 *= val1; break;
 102       case CDivULUL: *pop2 /= val1; break;
 103       case CModULUL: *pop2 %= val1; break;
 104       case CAndULUL: *pop2 &= val1; break;
 105       case COrULUL:  *pop2 |= val1; break;
 106       case CXorULUL: *pop2 ^= val1; break;
 107       case CLeftULUL:  *pop2 <<= val1; break;
 108       case CRightULUL: *pop2 >>= val1; break;
 109       case CLessULUL:     *( puint )pop2 = val2 < val1 ? 1 : 0; break;
 110       case CGreaterULUL:  *( puint )pop2 = val2 > val1 ? 1 : 0; break;
 111       case CEqULUL:       *( puint )pop2 = val1 == val2 ? 1 : 0; break;
 112       case CNotUL:        *pop1 = ~val1; break;
 113    }
 114 }
 115 
 116 //--------------------------------------------------------------------------
 117 
 118 void STDCALL pseudo_pul( pstackpos curpos )
 119 {
 120    pulong64   pop1 = ( pulong64 )curpos->top - 1;
 121    pulong64   pul = ( pulong64 )*( curpos->top - 1 );
 122    puint      pop2 = curpos->top - 3;
 123    ulong64    val1 = *pop1;
 124    uint       val2 = *pop2;
 125 
 126    switch ( *curpos->cmd )
 127    {
 128       case CIncLeftUL:  *( pulong64 )( curpos->top - 1 ) =  ++( *pul ); return;
 129       case CIncRightUL: *( pulong64 )( curpos->top - 1 ) =  ( *pul )++; return;
 130       case CDecLeftUL:  *( pulong64 )( curpos->top - 1 ) =  --( *pul ); return;
 131       case CDecRightUL: *( pulong64 )( curpos->top - 1 ) =  ( *pul )--; return;
 132       case CAddUL:   *( pulong64 )val2 += val1; break;
 133       case CSubUL:   *( pulong64 )val2 -= val1; break;
 134       case CMulUL:   *( pulong64 )val2 *= val1; break;
 135       case CDivUL:   *( pulong64 )val2 /= val1; break;
 136       case CModUL:   *( pulong64 )val2 %= val1; break;
 137       case CAndUL:   *( pulong64 )val2 &= val1; break;
 138       case COrUL:    *( pulong64 )val2 |= val1; break;
 139       case CXorUL:   *( pulong64 )val2 ^= val1; break;
 140       case CLeftUL:  *( pulong64 )val2 <<= val1; break;
 141       case CRightUL: *( pulong64 )val2 >>= val1; break;
 142    }
 143    *( pulong64 )pop2 = *( pulong64 )val2;
 144 }
 145 
 146 //--------------------------------------------------------------------------
 147 
 148 void STDCALL pseudo_l( pstackpos curpos )
 149 {
 150    plong64      pop1 = ( plong64 )curpos->top - 1;
 151    plong64      pop2 = ( plong64 )curpos->top - 2;
 152    long64       val1 = *pop1;
 153    long64       val2 = *pop2;
 154 
 155    switch ( *curpos->cmd )
 156    {
 157       case CMulLL: *pop2 *= val1; break;
 158       case CDivLL: *pop2 /= val1; break;
 159       case CModLL: *pop2 %= val1; break;
 160       case CLeftLL:    *pop2 <<= val1; break;
 161       case CRightLL:   *pop2 >>= val1; break;
 162       case CSignL:     *pop1 = -val1; break;
 163       case CLessLL:    *( puint )pop2 = val2 < val1 ? 1 : 0; break;
 164       case CGreaterLL: *( puint )pop2 = val2 > val1 ? 1 : 0; break;
 165    }
 166 }
 167 
 168 //--------------------------------------------------------------------------
 169 
 170 void STDCALL pseudo_pl( pstackpos curpos )
 171 {
 172    plong64    pop1 = ( plong64 )curpos->top - 1;
 173    puint      pop2 = curpos->top - 3;
 174    long64     val1 = *pop1;
 175    uint       val2 = *pop2;
 176 
 177    switch ( *curpos->cmd )
 178    {
 179       case CMulL:   *( plong64 )val2 *= val1; break;
 180       case CDivL:   *( plong64 )val2 /= val1; break;
 181       case CModL:   *( plong64 )val2 %= val1; break;
 182       case CLeftL:  *( plong64 )val2 <<= val1; break;
 183       case CRightL: *( plong64 )val2 >>= val1; break;
 184    }
 185    *( plong64 )pop2 = *( plong64 )val2;
 186 }
 187 
 188 //--------------------------------------------------------------------------
 189 
 190 void STDCALL pseudo_f( pstackpos curpos )
 191 {
 192    float*     pop1 = ( float* )curpos->top - 1;
 193    float*     pop2 = ( float* )curpos->top - 2;
 194    float      val1 = *pop1;
 195    float      val2 = *pop2;
 196 
 197    switch ( *curpos->cmd )
 198    {
 199       case CAddFF:  *pop2 += val1; break;
 200       case CSubFF:  *pop2 -= val1; break;
 201       case CMulFF:  *pop2 *= val1; break;
 202       case CDivFF:  *pop2 /= val1; break;
 203       case CSignF:  *pop1 = -val1; break;
 204       case CLessFF:    *( puint )pop2 = val2 < val1 ? 1 : 0; break;
 205       case CGreaterFF: *( puint )pop2 = val2 > val1 ? 1 : 0; break;
 206       case CEqFF:      *( puint )pop2 = val1 == val2 ? 1 : 0; break;
 207    }
 208 }
 209 
 210 //--------------------------------------------------------------------------
 211 
 212 void STDCALL pseudo_pf( pstackpos curpos )
 213 {
 214    float*     pop1 = ( float* )( curpos->top - 1 );
 215    float*     pf = ( float* )*( curpos->top - 1 );
 216    puint      pop2 = curpos->top - 2;
 217    float      val1 = *pop1;
 218    uint       val2 = *pop2;
 219 
 220    switch ( *curpos->cmd )
 221    {
 222       case CIncLeftF:  *pop1 =  ++(*pf); return;
 223       case CIncRightF: *pop1 = (*pf)++ ; return;
 224       case CDecLeftF:  *pop1 =  --(*pf); return;
 225       case CDecRightF: *pop1 =  (*pf)--; return;
 226       case CAddF:      *( float* )val2 += val1; break;
 227       case CSubF:      *( float* )val2 -= val1; break;
 228       case CMulF:      *( float* )val2 *= val1; break;
 229       case CDivF:      *( float* )val2 /= val1; break;
 230    }
 231    *( float* )pop2 = *( float* )val2;
 232 }
 233 
 234 //--------------------------------------------------------------------------
 235 
 236 void STDCALL pseudo_d( pstackpos curpos )
 237 {
 238    double*     pop1 = ( double* )curpos->top - 1;
 239    double*     pop2 = ( double* )curpos->top - 2;
 240    double      val1 = *pop1;
 241    double      val2 = *pop2;
 242 
 243    switch ( *curpos->cmd )
 244    {
 245       case CAddDD:  *pop2 += val1; break;
 246       case CSubDD:  *pop2 -= val1; break;
 247       case CMulDD:  *pop2 *= val1; break;
 248       case CDivDD:  *pop2 /= val1; break;
 249       case CSignD:  *pop1 = -val1; break;
 250       case CLessDD:    *( puint )pop2 = val2 < val1 ? 1 : 0; break;
 251       case CGreaterDD: *( puint )pop2 = val2 > val1 ? 1 : 0; break;
 252       case CEqDD:      *( puint )pop2 = val1 == val2 ? 1 : 0; break;
 253    }
 254 }
 255 
 256 //--------------------------------------------------------------------------
 257 
 258 void STDCALL pseudo_pd( pstackpos curpos )
 259 {
 260    double*    pop1 = ( double* )curpos->top - 1;
 261    double*    pd = ( double* )*( curpos->top - 1 );
 262    puint      pop2 = curpos->top - 3;
 263    double     val1 = *pop1;
 264    uint       val2 = *pop2;
 265 
 266    switch ( *curpos->cmd )
 267    {
 268       case CIncLeftD:  *( double* )( curpos->top - 1 ) =  ++( *pd ); return;
 269       case CIncRightD: *( double* )( curpos->top - 1 ) =  ( *pd )++; return;
 270       case CDecLeftD:  *( double* )( curpos->top - 1 ) =  --( *pd ); return;
 271       case CDecRightD: *( double* )( curpos->top - 1 ) =  ( *pd )--; return;
 272       case CAddD:  *( double* )val2 += val1; break;
 273       case CSubD:  *( double* )val2 -= val1; break;
 274       case CMulD:  *( double* )val2 *= val1; break;
 275       case CDivD:  *( double* )val2 /= val1; break;
 276    }
 277    *( double* )pop2 = *( double* )val2;
 278 }
 279 
 280 //--------------------------------------------------------------------------
 281 
 282 void STDCALL pseudo_ui( pstackpos curpos )
 283 {
 284    puint     pop1 = curpos->top - 1;
 285    puint     pop2 = curpos->top - 2;
 286    uint      val1 = *pop1;
 287    uint      val2 = *pop2;
 288 
 289    switch ( *curpos->cmd )
 290    {
 291       case CIncLeftUB:  *pop1 =  ++( *( pubyte )val1 ); break;
 292       case CIncRightUB: *pop1 =  ( *( pubyte )val1 )++; break;
 293       case CDecLeftUB:  *pop1 =  --( *( pubyte )val1 ); break;
 294       case CDecRightUB: *pop1 =  ( *( pubyte )val1 )--; break;
 295       case CAddUB:      *( pubyte )val2 += ( ubyte )val1; goto setub;
 296       case CSubUB:      *( pubyte )val2 -= ( ubyte )val1; goto setub;
 297       case CMulUB:      *( pubyte )val2 *= ( ubyte )val1; goto setub;
 298       case CDivUB:      *( pubyte )val2 /= ( ubyte )val1; goto setub;
 299       case CModUB:      *( pubyte )val2 %= ( ubyte )val1; goto setub;
 300       case CAndUB:      *( pubyte )val2 &= ( ubyte )val1; goto setub;
 301       case COrUB:       *( pubyte )val2 |= ( ubyte )val1; goto setub;
 302       case CXorUB:      *( pubyte )val2 ^= ( ubyte )val1; goto setub;
 303       case CLeftUB:     *( pubyte )val2 <<= ( ubyte )val1; goto setub;
 304       case CRightUB:    *( pubyte )val2 >>= ( ubyte )val1; goto setub;
 305       case CIncLeftUS:  *pop1 =  ++( *( pushort )val1 ); break;
 306       case CIncRightUS: *pop1 =  ( *( pushort )val1 )++; break;
 307       case CDecLeftUS:  *pop1 =  --( *( pushort )val1 ); break;
 308       case CDecRightUS: *pop1 =  ( *( pushort )val1 )--; break;
 309       case CAddUS:   *( pushort )val2 += ( ushort )val1; goto setus;
 310       case CSubUS:   *( pushort )val2 -= ( ushort )val1; goto setus;
 311       case CMulUS:   *( pushort )val2 *= ( ushort )val1; goto setus;
 312       case CDivUS:   *( pushort )val2 /= ( ushort )val1; goto setus;
 313       case CModUS:   *( pushort )val2 %= ( ushort )val1; goto setus;
 314       case CAndUS:   *( pushort )val2 &= ( ushort )val1; goto setus;
 315       case COrUS:    *( pushort )val2 |= ( ushort )val1; goto setus;
 316       case CXorUS:   *( pushort )val2 ^= ( ushort )val1; goto setus;
 317       case CLeftUS:  *( pushort )val2 <<= ( ushort )val1; goto setus;
 318       case CRightUS: *( pushort )val2 >>= ( ushort )val1; goto setus;
 319    }
 320    return;
 321 setub:
 322    *pop2 = *( pubyte )val2;
 323    return;
 324 setus:
 325    *pop2 = *( pushort )val2;
 326 }
 327 
 328 //--------------------------------------------------------------------------
 329 
 330 void STDCALL pseudo_collectadd( pstackpos curpos )
 331 {
 332    uint       num, i, count = *( curpos->cmd + 1 );
 333    puint      start = curpos->top - count;
 334    pcollect   pclt;
 335    buf        stack;
 336    puint      cur = curpos->top - 1;
 337 
 338    pclt = ( pcollect )*( start - 1 );
 339 
 340    buf_reserve( buf_init( &stack ), 128 );
 341    i = count;
 342    if ( count > 2 || ( *cur >> 24 ))
 343    {
 344       buf_clear( &pclt->data );
 345       pclt->count = 0;
 346    }
 347    while ( i )
 348    {
 349       num = *cur >> 24;
 350       if ( !num )
 351          num = 1;
 352       buf_appenduint( &stack, num );
 353       buf_appenduint( &stack, *cur & 0xFFFFFF );
 354 //      print("Num=%i Cur = %i\n", num, *cur & 0xFFFFFF );
 355       cur--;
 356       i -= 1 + num;
 357    }
 358    while ( stack.use )
 359    {
 360       stack.use -= 8;
 361       num = *( puint )( stack.data + stack.use );
 362       while ( num )
 363       {
 364          i = collect_add( pclt, start, *( puint )( stack.data + 
 365                             stack.use + 4 ) ) - start;
 366          num -= i;
 367          start += i;
 368       }
 369 //      start++;
 370    }
 371    buf_delete( &stack );
 372    curpos->top -= count;
 373 }
 374 
 375 /*-----------------------------------------------------------------------------
 376 *
 377 * ID: vm_run 26.12.06 0.0.A.
 378 * 
 379 * Summary: Execute VM
 380 *
 381 * Params: vmp - virtual machine
 382           id - the id of the func to run
 383           params - The pointer to parameters
 384           result - The pointer for getting the result value
 385 *
 386 -----------------------------------------------------------------------------*/
 387 
 388 //puint        ivm;
 389 
 390 uint  STDCALL vm_run( uint id, puint params, puint result, uint stacksize )
 391 {
 392 //register  puint    ivm;
 393    uint         cmd, i;
 394    puint        stack;       // The main stack
 395 // слева у стэка идет стэк значений, а справа навстречу ему стэк состояний 
 396 // вызовов
 397    pstackpos    curpos;      // текущее состояние вызова
 398    pstackpos    endpos;      // первоначальное состояние вызова
 399    uint         load[2];     // load id + return
 400    uint         uiret;       // The count of return uints
 401    pvmfunc      curfunc;     // текущий байт-код
 402 //   pvmobj       obj;
 403    pvoid        exfunc;
 404    uint         val1, val2;
 405    puint        pop1, pop2;
 406    puint        top;
 407    double       d;
 408    uint         val, valhi;
 409    pvartype     pvar;
 410    pvarset      pset;
 411    povmbcode    bcode;
 412    povmtype     ptype;
 413 
 414    stack = ( puint )mem_alloc( stacksize );
 415 
 416    curpos = ( pstackpos )( ( pubyte )stack + stacksize - sizeof( stackpos ));
 417    endpos = curpos;
 418    curpos->start = stack;
 419 
 420    load[ 0 ] = id;
 421    load[ 1 ] = CReturn;
 422 
 423    curpos->cmd = ( puint )&load;
 424 
 425    if ( id >= _vm.count )
 426    {
 427       cmd = id;
 428       goto error;
 429    }
 430 //   pcmd = ( puint )arr_ptr( &vmp->objtbl, 0 );
 431 
 432    curfunc = ( pvmfunc )PCMD( id );// pcmd + id );
 433    uiret = curfunc->dwret;
 434    curpos->top = curpos->start;
 435    
 436    // Для text функции определяем стандартный вывод как 0
 437    if ( curfunc->vmo.flag & GHBC_TEXT )
 438       *curpos->top++ = 0;
 439 
 440 // заносим в стэк параметры
 441    if ( params )
 442    {
 443       mem_copyui( curpos->top, params, curfunc->parsize );
 444       curpos->top += curfunc->parsize;
 445    }
 446    curpos->clmark = curpos->top;
 447 //   print("Func=%x %s id=%i pars=%i Val=%x\n", 
 448 //          curfunc, curfunc->vmobj.name, id, curfunc->dwpars, *curpos->start );
 449    while ( 1 )
 450    {
 451       // Берем команду
 452       if (( cmd = *curpos->cmd ) >= _vm.count )
 453          goto error;
 454 //      if ( (uint)curpos->cmd & 3 || (uint)curpos->top & 3 )
 455 //         print("CMD=%x\n", cmd );
 456 stackcmd:
 457 //      obj = *( pvmobj* )( pcmd + cmd );
 458       curfunc = ( pvmfunc )PCMD( cmd );
 459       switch ( curfunc->vmo.type )
 460       {
 461          case OVM_STACKCMD: goto stack;
 462          case OVM_PSEUDOCMD: goto pseudo;
 463          case OVM_BYTECODE: goto bcode;
 464          case OVM_EXFUNC: goto exfunc;
 465          case OVM_TYPE: goto type;
 466       }
 467       goto error;
 468 //----------------   Stack commands --------------------------------------
 469 stack:
 470       pop1 = curpos->top - 1;
 471       val1 = *pop1;
 472       pop2 = curpos->top - 2;
 473       val2 = *pop2;
 474 //      print("%x 1=%i 2=%i\n", curpos->top, val1, val2 );
 475       switch ( cmd )
 476       {
 477          case CNop: break;
 478          case CGoto: 
 479             curpos->top = curpos->clmark;
 480          case CGotonocls:
 481             curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 ) - 2;
 482             break;
 483          case CIfze:
 484             curpos->top = curpos->clmark;
 485          case CIfznocls:
 486             if ( !val1 )
 487             {
 488                curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 489                continue;
 490             }
 491             break;
 492          case CIfnze:
 493             curpos->top = curpos->clmark;
 494          case CIfnznocls:
 495             if ( val1 )
 496             {
 497                curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 498                continue;
 499             }
 500             break;
 501          case CDwload:
 502          case CCmdload:
 503          case CResload:
 504             *curpos->top = *( curpos->cmd + 1 );
 505             break;
 506          case CQwload:
 507             *( pulong64 )curpos->top = *( pulong64 )( curpos->cmd + 1 );
 508             break;
 509          case CDwsload:
 510             val = *++curpos->cmd;
 511             while ( val-- )
 512                *curpos->top++ = *++curpos->cmd;
 513             break;
 514          case CVarload:
 515          case CVarptrload:
 516             i = *( curpos->cmd + 1 );
 517             if ( i < curpos->func->parcount )
 518             {
 519                pvar = curpos->func->params + i;
 520                top = curpos->start + pvar->off;
 521             }
 522             else
 523             {
 524                pvar = BCODE( curpos )->vars + ( i - curpos->func->parcount );
 525                top = ( puint )*( curpos->start + curpos->func->parsize ) +
 526                       pvar->off;
 527             }
 528             ptype = ( povmtype )PCMD( pvar->type );
 529 //            pvari = curpos->func->parvar + *( curpos->cmd + 1 ); 
 530 //            top = curpos->start + pvari->off;
 531             if ( cmd == CVarload && ptype->vmo.flag & GHTY_STACK ) 
 532             {
 533                *curpos->top = *top;
 534                if ( ptype->stsize > 1 )
 535                   *++curpos->top = *++top;
 536             }
 537             else
 538             {
 539                if ( pvar->flag & VAR_PARAM && //i < curpos->func->parcount && 
 540                     !( ptype->vmo.flag & GHTY_STACK ))
 541                   top = ( puint )*top; // For parameters
 542                *curpos->top = ( uint )top;
 543             }
 544 //            print("VARLOAD = ptr = %x %x off = %i %i\n", 
 545 //                      top, *top, pvar->off, i );
 546             break;
 547          case CDatasize:
 548             val = *++curpos->cmd;
 549             *curpos->top++ = ( uint )++curpos->cmd;
 550             // Увеличиваем на 3 : 2 вместо 1 : 0 из-за команда и размера
 551             curpos->cmd += ( val >> 2 ) + ( val & 3 ? 1 : 0 );
 552             *curpos->top++ = val;
 553             continue;
 554          case CLoglongtrue: *pop2 = ( val1 || val2 ? 1 : 0 );  break;
 555          case CLognot:      *pop1 = !val1; break;
 556          case CLoglongnot:  *pop2 = ( val1 || val2 ? 0 : 1 ); break;
 557          case CDup:         *curpos->top = *pop1; break;
 558          case CDuplong:
 559             *curpos->top = *pop2;
 560             *( curpos->top + 1 ) = *pop1;
 561             break;
 562          case CTop: *curpos->top = ( uint )( curpos->top ); break;
 563          case CPop: break;
 564          case CGetUB: *pop1 = *( pubyte )val1; break;
 565          case CGetB:  *( int *)pop1 = ( int )*( pchar )val1; break;
 566          case CGetUS: *pop1 = *( pushort )val1; break;
 567          case CGetS:  *( int *)pop1 = ( int )*( pshort )val1; break;
 568          case CGetI: *pop1 = *( puint )val1; break;
 569          case CGetL: *( pulong64 )pop1 = *( pulong64 )val1; break;
 570          case CSetUB: 
 571          case CSetB:
 572             *( pubyte )val2 = ( ubyte )val1; goto set;
 573 //         case CSetB:  *( pchar )val2 = ( byte )val1; goto set;
 574          case CSetUS: 
 575          case CSetS:
 576             *( pushort )val2 = ( ushort )val1; goto set;
 577 //         case CSetS:  *( pshort )val2 = ( short )val1; goto set;
 578          case CSetI:  *( puint )val2 = val1; goto set;
 579          case CSetL: 
 580             *( pulong64 )*( curpos->top - 3 ) = *( pulong64 )pop2;
 581             *( curpos->top - 3 ) = val2; 
 582             goto set;
 583          case CAddUIUI:  *pop2 += val1; break;
 584          case CSubUIUI:  *pop2 -= val1; break;
 585          case CMulUIUI:  *pop2 *= val1; break;
 586          case CDivUIUI:  *pop2 /= val1; break;
 587          case CModUIUI:  *pop2 %= val1; break;
 588          case CAndUIUI:  *pop2 &= val1; break;
 589          case COrUIUI:   *pop2 |= val1; break;
 590          case CXorUIUI:  *pop2 ^= val1; break;
 591          case CLeftUIUI: *pop2 <<= val1; break;
 592          case CRightUIUI:   *pop2 >>= val1; break;
 593          case CLessUIUI:    *pop2 = val2 < val1 ? 1 : 0; break;
 594          case CGreaterUIUI: *pop2 = val2 > val1 ? 1 : 0; break;
 595          case CEqUIUI:      *pop2 = val1 == val2 ? 1 : 0; break;
 596          case CNotUI:       *pop1 = ~val1; break;
 597          case CIncLeftUI:   *pop1 =  ++( *( puint )val1 ); break;
 598          case CIncRightUI:  *pop1 =  ( *( puint )val1 )++; break;
 599          case CDecLeftUI:   *pop1 =  --( *( puint )val1 ); break;
 600          case CDecRightUI:  *pop1 =  ( *( puint )val1 )--; break;
 601          case CAddUI:   *( puint )val2 += val1; goto setui;
 602          case CSubUI:   *( puint )val2 -= val1; goto setui;
 603          case CMulUI:   *( puint )val2 *= val1; goto setui;
 604          case CDivUI:   *( puint )val2 /= val1; goto setui;
 605          case CModUI:   *( puint )val2 %= val1; goto setui;
 606          case CAndUI:   *( puint )val2 &= val1; goto setui;
 607          case COrUI:    *( puint )val2 |= val1; goto setui;
 608          case CXorUI:   *( puint )val2 ^= val1; goto setui;
 609          case CLeftUI:  *( puint )val2 <<= val1; goto setui;
 610          case CRightUI: *( puint )val2 >>= val1; goto setui;
 611          case CVarsInit:  type_setinit( curpos, *( curpos->cmd + 1 )); break;
 612          case CGetText: *curpos->top = curpos->func->vmo.flag & GHBC_TEXT ? 
 613                              *( curpos->start - 1 ) : 0; break; 
 614          case CSetText: 
 615             if ( curpos->func->vmo.flag & GHBC_TEXT && 
 616                   ( val2 = *( curpos->start - 1 )) )
 617                str_add( ( pstr )val2, ( pstr )val1 );
 618             else
 619                str_output( ( pstr )val1 );
 620             break;
 621          case CPtrglobal:
 622             *curpos->top = ( uint )(( povmglobal )
 623                            PCMD( *( curpos->cmd + 1 )))->pval;
 624 //            print("Global PTR %x %i\n", *curpos->top, *( puint )*curpos->top );
 625             break;
 626          case CSubcall:
 627             // Меняем стэк 
 628             *curpos->top++ = ( uint )( curpos->cmd + 2 ); // указатель на команду после выхода
 629             *curpos->top++ = ( uint )curpos->clmark;  // текущее значение clmark 
 630             *curpos->top++ = 0;               // Количество возвращаемых dword 
 631             *curpos->top++ = 0;               // Количество полученных dword в качестве параметров
 632             curpos->clmark = curpos->top;     // Новое значение clmark
 633             // Указатель на первую команду подфункции
 634             curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 635             continue;
 636          case CSubret:
 637             *( curpos->clmark - 2 ) = *( curpos->cmd + 1 );
 638             break;
 639          case CSubpar:
 640             pset = BCODE( curpos )->sets + *( curpos->cmd + 1 );
 641             // копируем значения переменных из стэка
 642             pvar = BCODE( curpos )->vars + pset->first;
 643             top = ( puint )*( curpos->start + curpos->func->parsize ) + pvar->off;
 644 
 645 //            top = curpos->start + ( curpos->func->varb + *++curpos->cmd)->firstoff;
 646 //            curpos->cmd++;
 647 //            print("Top=%i %i\n", *top, *( top + 1 ));
 648             mem_copyui( top,  curpos->clmark - 4 - pset->size, pset->size );
 649             *( curpos->clmark - 1 ) = pset->size;
 650             break;
 651          case CSubreturn:
 652             // Выход из подфункции
 653             top = curpos->clmark - 4;  // Указатель на старый top 
 654             // Восстанавливаем команду
 655             curpos->cmd = ( puint )*top;
 656             curpos->clmark = ( puint )*( top + 1 );
 657             i = *( top + 2 );
 658             // записываем возвращаемое значение
 659             if ( i )
 660                mem_copyui( top - *( top + 3 ), curpos->top - i, i );
 661                // Устанавливаем стэк
 662             curpos->top = top + i - *( top + 3 );
 663             continue;
 664          case CCmdcall:
 665             // Берем из стэка код команды
 666             top = curpos->top - *++curpos->cmd - 1;
 667             cmd = *top;
 668             // Сдвигаем параметры вызова в стэке
 669             mem_copyui( top, top + 1, *curpos->cmd );
 670             // сразу устанавливаем указатель на следующую команду
 671             curpos->top--;
 672             goto stackcmd;
 673          case CCallstd:
 674             val1 = *++curpos->cmd;  // Флаги вызова
 675             val2 = *++curpos->cmd;  // Размер параметров
 676             top = curpos->top;
 677             for ( i = 0; i < val2; i++ )
 678             {
 679                val = *--top;
 680 #ifdef LINUX
 681     	         __asm__ ("push %0"::"d"(val));
 682 #else
 683    #if defined ( __GNUC__) || defined (__TINYC__)
 684                __asm__ ("push %0"::"d"(val));
 685    #else
 686                _asm {
 687                   push val
 688                }
 689    #endif
 690 #endif
 691             }  
 692             exfunc = ( pvoid )*--top;
 693 #ifdef LINUX
 694             __asm__ ("call *%0"::"m"(exfunc));
 695             __asm__ ("mov %%eax,%0":"m="(val));
 696             __asm__ ("mov %%edx,%0":"m="(valhi));
 697 #else
 698    #if defined (__GNUC__) 
 699   
 700             __asm__ ("call *%0"::"m"(exfunc));
 701             __asm__ ("mov %%eax,%0":"m="(val));
 702             __asm__ ("mov %%edx,%0":"m="(valhi));
 703   
 704    #elif  defined (__TINYC__)
 705             __asm__ ("call *%0"::"m"(exfunc));
 706             __asm__ ("mov %%eax,%0":"m"(val));
 707             __asm__ ("mov %%edx,%0":"m"(valhi));
 708    #else
 709             _asm {
 710                call exfunc
 711                mov  val,eax
 712                mov  valhi,edx
 713             }
 714    #endif
 715 #endif
 716 
 717 #ifdef LINUX
 718 #else
 719             if ( val1 )// & GHEX_CDECL )
 720 #endif
 721             {
 722                i = val2 << 2;
 723 #ifdef LINUX
 724                __asm__ ("add %0, %%esp"::"m"(i));
 725 #else
 726    #if defined ( __GNUC__) || defined (__TINYC__)
 727                __asm__ ("add %0, %%esp"::"m"(i));
 728    #else
 729                _asm {
 730                   add esp, i
 731                }
 732    #endif
 733 #endif
 734             }
 735 //          if ( (( psovmfunc )curfunc)->dwret )
 736             *top++ = val;
 737             curpos->top = top;
 738             curpos->cmd++;
 739             continue;
 740          case CReturn:
 741             if ( curpos == endpos )  // Все выполнили
 742                goto end;  
 743             // !!! Insert exception here
 744 /*               if ( vm->lastexcept->start == curpos->start )
 745                {
 746                   vm->lastexcept--;
 747                }*/
 748             if ( _gentee.debug )
 749                _gentee.debug( curpos ); 
 750 
 751             // Free all variables
 752             bcode = BCODE( curpos );
 753 
 754             if ( bcode->setcount )
 755             {
 756                for ( i = 0; i < bcode->setcount; i++ )
 757                   type_setdelete( curpos, i );
 758                // Освобождаем память под структуры
 759 //    ???      if ( *( curpos->start + pbcode->dwsize - 1 ))
 760                if ( bcode->varsize > VAR_SIZE )
 761                   mem_free( ( pvoid )*( curpos->start + curpos->func->parsize ));
 762             }
 763             // Возвращаемся в предыдущее состояние
 764             // если функция возвращает значение, то сохраняем необходимое 
 765             // количество верхних элементов
 766             if ( curpos->uiret )
 767             {
 768                mem_copyui( ( curpos + 1 )->top, curpos->top - curpos->uiret,
 769                            curpos->uiret );
 770                ( curpos + 1 )->top += curpos->uiret;
 771             }
 772             curpos++;
 773 /*            if ( exceptfunc )
 774                {
 775                   curpos->cmd = curpos->func->finally;
 776                   *curpos->top++ = 0;
 777                   *curpos->top++ = 0;
 778                   if ( curpos->start == exceptfunc ) 
 779                      exceptfunc = 0;
 780                   continue;
 781                }*/
 782             // cmdshift for CReturn == 1 - shift the calling command
 783             break;
 784          case CAsm:
 785 #ifdef _ASM
 786             val1 = (uint)(curpos->cmd + 2);
 787             val2 = (uint)curpos->start; 
 788             pop2 = ( puint )*( curpos->start + curpos->func->parsize );
 789             //print( "ASM0 %x %x\n", curpos->top, curpos->cmd );
 790             __asm {    
 791             //pushad
 792             push edi
 793             push esi            
 794             push ebp       //Сохранение машинной базы беременных
 795             push ebx
 796             pushf
 797             mov  ecx, curpos
 798             
 799             mov  edi, pop2 //Переменные
 800             mov  esi, pop1 //Новый указатель стэка
 801             mov  eax, val1 //Адрес блока машинных кодов  
 802             mov  ebp, val2 //Адрес блока параметров
 803             
 804             std
 805             call eax
 806             popf
 807             //cld
 808             pop  ebx
 809             pop  ebp       //Восстановление машинной базы переменных
 810             //mov  pop1, esi//ebx 
 811             
 812             add  esi, 4
 813             mov  dword ptr [ecx+0x08], esi           
 814             
 815             mov  dword ptr [ecx+0x04], eax
 816 
 817             pop  esi
 818             pop  edi
 819             }
 820             curpos->cmd = (uint)curpos->cmd + ( puint )curpos->func->func;            
 821             //print( "ASM1 %x %x %x\n", curpos->top, curpos->cmd, curfunc->func );            
 822             continue;   
 823 #else
 824             break;
 825 #endif  // _ASM
 826 #ifndef RUNTIME
 827          case CDbgTrace:
 828          case CDbgFunc:
 829             if ( _gentee.debug )
 830             {
 831                curpos->nline = ( cmd == CDbgFunc ? *( puint )val2 : val1 ); 
 832                _gentee.debug( curpos );
 833             }
 834             break;
 835 #endif
 836       }
 837       goto shift;
 838 pseudo:   // Pseudo stack commands
 839       (( stackfunc )curfunc->func)( curpos );
 840       goto shift;
 841 set:
 842       *pop2 = val1; goto shift;
 843 setui:
 844       *pop2 = *( puint )val2; goto shift;
 845 
 846 shift:
 847       curpos->top += (( povmstack )curfunc)->topshift;
 848       curpos->cmd += (( povmstack )curfunc)->cmdshift;
 849       continue;
 850 //----------------   Bytecode command --------------------------------------
 851 bcode:
 852       // Проверка переполнения стэка
 853       if ( curpos->top + 128 > ( puint )curpos )
 854          msg( MFullstack | MSG_DVAL, stacksize );
 855       // Сохраняем текущее состояние увеличив стэк
 856       curpos->top -= curfunc->parsize;
 857       curpos--;
 858       curpos->cmd = curfunc->func;
 859       curpos->start = ( curpos + 1 )->top;
 860 
 861       curpos->top = curpos->start + curfunc->parsize + 1 + 
 862                    (( povmbcode )curfunc)->setcount;
 863       if ( (( povmbcode )curfunc)->varsize > VAR_SIZE )
 864       {
 865          // All variable are in the extern memory
 866          ( puint )*( curpos->start + curfunc->parsize ) = mem_alloc( (( povmbcode )curfunc)->varsize << 2 );
 867       }
 868       else
 869       {  // All variables are in the stack
 870          ( puint )*( curpos->start + curfunc->parsize ) = curpos->top;
 871          curpos->top += (( povmbcode )curfunc)->varsize;
 872       }
 873       curpos->clmark = curpos->top;
 874       curpos->uiret = curfunc->dwret;
 875       curpos->func = curfunc;
 876       // Зануляем признак отведения памяти для локальных структур
 877 //      *( curpos->top - 1 ) = 0;
 878 
 879       // Зануляем признаки инициализации блоков переменных
 880       if ( (( povmbcode )curfunc)->setcount )
 881          mem_zeroui( curpos->start + curfunc->parsize + 1, 
 882                      (( povmbcode )curfunc)->setcount );
 883       if ( !curpos->cmd )
 884          msg( MUndefcmd | MSG_VALSTRERR, curfunc->vmo.name, cmd );
 885       continue;
 886 
 887 //----------------   Exfunc commands --------------------------------------
 888 exfunc:
 889       exfunc = curfunc->func;
 890       if ( !exfunc )
 891          msg( MUndefcmd | MSG_VALSTRERR, curfunc->vmo.name, cmd );
 892       top = curpos->top;
 893 
 894 #ifdef LINUX
 895 		if ( curfunc->vmobj.flag & GHEX_SYSCALL )
 896       {
 897          curpos->top = syscall( curfunc, top );
 898          goto next;
 899       }
 900 #endif
 901 //      print("PAR=%i parsize=%i ret=%i %s\n", curfunc->parcount,
 902 //              curfunc->parsize, curfunc->dwret, curfunc->vmo.name );
 903       for ( i = 0; i < curfunc->parsize; i++ )
 904       {
 905          val = *--top;
 906 #ifdef LINUX
 907       	__asm__ ("push %0"::"d"(val));
 908 #else
 909    #if defined (__GNUC__) || defined (__TINYC__)
 910       	__asm__ ("push %0"::"d"(val));
 911    #else
 912          _asm { push val }
 913    #endif
 914 #endif
 915       }
 916       if ( curfunc->vmo.flag & GHEX_FLOAT )
 917       {
 918          if ( curfunc->dwret == 1 )
 919          {
 920 #ifdef LINUX
 921             __asm__ ("call *%0"::"m"(exfunc));
 922            	__asm__ ("fstp %%st":"=m"(val));
 923 #else
 924    #if defined ( __GNUC__) || defined (__TINYC__)
 925             __asm__ ("call *%0"::"m"(exfunc));
 926             __asm__ ("fstp %%st":"=m"(val));
 927 
 928    #else
 929             _asm {
 930                call exfunc
 931                fstp dword ptr [val]
 932             }
 933    #endif
 934 #endif
 935          }
 936          else
 937          {
 938 #ifdef LINUX
 939             __asm__ ("call *%0"::"m"(exfunc));
 940 	         __asm__ ("fstp %%st":"=t"(d):"0"(d));
 941    		   //__asm__ ("fstp %0":"=r"(&d));
 942 #else
 943    #if defined (__GNUC__) 
 944             __asm__ ("call *%0"::"m"(exfunc));
 945 	         __asm__ ("fstp %%st":"=t"(d):"0"(d));
 946    	    //__asm__ ("fstp %0":"=r"(&d));
 947    #elif defined (__TINYC__)
 948             __asm__ ("call *%0"::"m"(exfunc));
 949             __asm__ ("fstp %%st":"m"(d):"0"(d));
 950    #else 
 951             _asm {
 952                call exfunc
 953 //             fstp qword ptr [d]
 954                fstp d
 955             }
 956    #endif
 957 #endif
 958             val = *(uint*)&d;
 959             valhi = *((uint*)&d + 1 );
 960          }
 961       }
 962       else
 963       {
 964 #ifdef LINUX
 965          //print( "\07exfunc=%x val=%x\n", exfunc, val );
 966          __asm__ ("call *%0"::"m"(exfunc));
 967          __asm__ ("mov %%eax,%0":"m="(val));
 968          __asm__ ("mov %%edx,%0":"m="(valhi));
 969 #else
 970    #if defined (__GNUC__) 
 971          __asm__ ("call *%0"::"m"(exfunc));
 972          __asm__ ("mov %%eax,%0":"m="(val));
 973          __asm__ ("mov %%edx,%0":"m="(valhi));
 974    #elif defined (__TINYC__)
 975          __asm__ ("call *%0"::"m"(exfunc));
 976          __asm__ ("mov %%eax,%0":"m"(val));
 977          __asm__ ("mov %%edx,%0":"m"(valhi));
 978    #else
 979          _asm {
 980             call exfunc
 981             mov  val,eax
 982             mov  valhi,edx
 983          }
 984    #endif
 985 #endif
 986       }
 987 #ifdef LINUX
 988 #else
 989       if ( curfunc->vmo.flag & GHEX_CDECL )
 990 #endif
 991       {
 992          i = curfunc->parsize << 2;
 993 #ifdef LINUX
 994          __asm__ ("add %0, %%esp"::"m"(i));
 995 #else
 996    #if defined (__GNUC__) || defined (__TINYC__)
 997          __asm__ ("add %0, %%esp"::"m"(i));
 998    #else
 999          _asm { add esp, i }
1000    #endif
1001 #endif
1002       }
1003       if ( curfunc->dwret )
1004          *top++ = val;
1005       if ( curfunc->dwret == 2 )
1006          *top++ = valhi;
1007       curpos->top = top;
1008       goto next;
1009 
1010 //----------------   Type command --------------------------------------
1011 type:
1012       *curpos->top++ = cmd;
1013       goto next;
1014 
1015 //----------------   Getting next command ------------------------------
1016 next:
1017       curpos->cmd++;
1018    }
1019 
1020 end:
1021 // Copy the result value
1022    if ( result )
1023       mem_copyui( result, curpos->top - uiret, uiret );
1024 // Free stack
1025    mem_free( stack );
1026 
1027    return 1;
1028 error:
1029    msg( MUnkbcode | MSG_DVAL, cmd );
1030    return 0;
1031 }
1032 
1033 //--------------------------------------------------------------------------
1034 
1035 uint  STDCALL vm_runone( uint id, uint first )
1036 {
1037    uint  ret;
1038    // Изменяем размеры стэка для функций вызываемых из виртуальной машины
1039 //   _vm.stacksize = 8192;
1040    vm_run( id, &first, &ret, 8192 );
1041 //   _vm.stacksize = size;
1042    return ret;
1043 }
1044 
1045 //--------------------------------------------------------------------------
1046 
1047 uint  STDCALL vm_runtwo( uint id, uint first, uint second )
1048 {
1049    uint  ret;
1050 //   uint  size = _vm.stacksize;
1051    uint  params[4];
1052 
1053    // Изменяем размеры стэка для функций вызываемых из виртуальной машины
1054 //   _vm.stacksize = 8192;
1055    params[0] = first;
1056    params[1] = second;
1057    vm_run( id, ( puint )¶ms, &ret, 8192 );
1058 //   _vm.stacksize = size;
1059    return ret;
1060 }
1061 
1062 /*-----------------------------------------------------------------------------
1063 ** Id: gentee_call F
1064 * 
1065 * Summary: Call the function from the bytecode. The bytecode should be 
1066            previously loaded with the $[gentee_load] or $[gentee_compile]
1067            functions. 
1068 *
1069 * Params: id - The identifier of the called object. Can be obtained by /
1070                $[gentee_getid] function.
1071           result - Pointer to the memory space, to which the result will be /
1072                    written. It can be the pointer to #b(uint), #b(long) or  /
1073                    #b(double).
1074           ... - Required parameters of the function. 
1075 *
1076 * Return: #lng/retf#
1077 *  
1078 -----------------------------------------------------------------------------*/
1079 
1080 uint  CDECLCALL gentee_call( uint id, puint result, ... )
1081 {
1082    uint        ok = 0;
1083    pvmfunc     curfunc;
1084    va_list     argptr;
1085    uint        i = 0;
1086    uint        params[ 64 ];
1087 //   uint        size = _vm.stacksize;
1088 
1089 //   _vm.stacksize = 0x8000; // 32KB
1090    va_start( argptr, result );
1091    
1092    curfunc = ( pvmfunc )PCMD( id );
1093    if ( curfunc->vmo.flag & GHRT_MAYCALL )
1094    {
1095       while ( i < curfunc->parsize )
1096          params[ i++ ] = va_arg( argptr, uint );
1097 
1098       ok = vm_run( id, ( puint )¶ms, result, 0x8000 );
1099    }
1100    va_end( argptr );
1101 //   _vm.stacksize = size;
1102 
1103    return ok;
1104 }
1105 
1106 uint  STDCALL vm_calladdr( void )
1107 {
1108    return ( uint )&gentee_call;
1109 }
1110 
1111 //-----------------------------------------------------------------------------