EnglishРусский  

   ..

   vm.c

   vm.h

   vmload.c

   vmload.h

   vmres.c

   vmres.h

   vmrun.c

   vmrun.h

   vmtype.c

   vmtype.h

Ads

Perfect Automation tool
All-In-One: Script editor, Launcher, Scheduler, Keyboard & Mouse Recorder. Try now!

CreateInstall
Freeware and commercial installers.

Cell Phone Batteries
Batteries Plus offers batteries for laptop, camcorder, cell phone, camera.

Gentee needs your help!
How to advertise with us
 
laptop battery

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;
  38       case CDivII:   *pop2 /= val1; break;
  39       case CModII:   *pop2 %= val1; break;
  40       case CLeftII:  *pop2 <<= val1; break;
  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;
  46       case CDivI:   *( pint )val2 /= val1; goto seti;
  47       case CModI:   *( pint )val2 %= val1; goto seti;
  48       case CLeftI:  *( pint )val2 <<= val1; goto seti;
  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 
 343    while ( i )
 344    {
 345       num = *cur >> 24;
 346       buf_appenduint( &stack, num );
 347       buf_appenduint( &stack, *cur & 0xFFFFFF );
 348 //      print("Num=%i Cur = %i\n", num, *cur & 0xFFFFFF );
 349       cur--;
 350       i -= 1 + num;
 351    }
 352    while ( stack.use )
 353    {
 354       stack.use -= 8;
 355       num = *( puint )( stack.data + stack.use );
 356       while ( num )
 357       {
 358          i = collect_add( pclt, start, *( puint )( stack.data + 
 359                             stack.use + 4 ) ) - start;
 360          num -= i;
 361          start += i;
 362       }
 363 //      start++;
 364    }
 365    buf_delete( &stack );
 366    curpos->top -= count;
 367 }
 368 
 369 /*-----------------------------------------------------------------------------
 370 *
 371 * ID: vm_run 26.12.06 0.0.A.
 372 * 
 373 * Summary: Execute VM
 374 *
 375 * Params: vmp - virtual machine
 376           id - the id of the func to run
 377           params - The pointer to parameters
 378           result - The pointer for getting the result value
 379 *
 380 -----------------------------------------------------------------------------*/
 381 
 382 //puint        ivm;
 383 
 384 uint  STDCALL vm_run( uint id, puint params, puint result )
 385 {
 386 //register  puint    ivm;
 387    uint         cmd, i;
 388    puint        stack;       // The main stack
 389 // слева у стэка идет стэк значений, а справа навстречу ему стэк состояний 
 390 // вызовов
 391    pstackpos    curpos;      // текущее состояние вызова
 392    pstackpos    endpos;      // первоначальное состояние вызова
 393    uint         load[2];     // load id + return
 394    uint         uiret;       // The count of return uints
 395    pvmfunc      curfunc;     // текущий байт-код
 396 //   pvmobj       obj;
 397    pvoid        exfunc;
 398    uint         val1, val2;
 399    puint        pop1, pop2;
 400    puint        top;
 401    double       d;
 402    uint         val, valhi;
 403    pvartype     pvar;
 404    pvarset      pset;
 405    povmbcode    bcode;
 406    povmtype     ptype;
 407 
 408    stack = ( puint )mem_alloc( _vm.stacksize );
 409 
 410    curpos = ( pstackpos )( ( pubyte )stack + _vm.stacksize - sizeof( stackpos ));
 411    endpos = curpos;
 412    curpos->start = stack;
 413 
 414    load[ 0 ] = id;
 415    load[ 1 ] = CReturn;
 416 
 417    curpos->cmd = ( puint )&load;
 418 
 419    if ( id >= _vm.count )
 420    {
 421       cmd = id;
 422       goto error;
 423    }
 424 //   pcmd = ( puint )arr_ptr( &vmp->objtbl, 0 );
 425 
 426    curfunc = ( pvmfunc )PCMD( id );// pcmd + id );
 427    uiret = curfunc->dwret;
 428    curpos->top = curpos->start;
 429    
 430    // Для text функции определяем стандартный вывод как 0
 431    if ( curfunc->vmo.flag & GHBC_TEXT )
 432       *curpos->top++ = 0;
 433 
 434 // заносим в стэк параметры
 435    if ( params )
 436    {
 437       mem_copyui( curpos->top, params, curfunc->parsize );
 438       curpos->top += curfunc->parsize;
 439    }
 440    curpos->clmark = curpos->top;
 441 //   print("Func=%x %s id=%i pars=%i Val=%x\n", 
 442 //          curfunc, curfunc->vmobj.name, id, curfunc->dwpars, *curpos->start );
 443    while ( 1 )
 444    {
 445       // Берем команду
 446       if (( cmd = *curpos->cmd ) >= _vm.count )
 447          goto error;
 448 //      if ( (uint)curpos->cmd & 3 || (uint)curpos->top & 3 )
 449 //         print("CMD=%x\n", cmd );
 450 stackcmd:
 451 //      obj = *( pvmobj* )( pcmd + cmd );
 452       curfunc = ( pvmfunc )PCMD( cmd );
 453       switch ( curfunc->vmo.type )
 454       {
 455          case OVM_STACKCMD: goto stack;
 456          case OVM_PSEUDOCMD: goto pseudo;
 457          case OVM_BYTECODE: goto bcode;
 458          case OVM_EXFUNC: goto exfunc;
 459          case OVM_TYPE: goto type;
 460       }
 461       goto error;
 462 //----------------   Stack commands --------------------------------------
 463 stack:
 464       pop1 = curpos->top - 1;
 465       val1 = *pop1;
 466       pop2 = curpos->top - 2;
 467       val2 = *pop2;
 468 //      print("%x 1=%i 2=%i\n", curpos->top, val1, val2 );
 469       switch ( cmd )
 470       {
 471          case CNop: break;
 472          case CGoto: 
 473             curpos->top = curpos->clmark;
 474          case CGotonocls:
 475             curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 ) - 2;
 476             break;
 477          case CIfze:
 478             curpos->top = curpos->clmark;
 479          case CIfznocls:
 480             if ( !val1 )
 481             {
 482                curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 483                continue;
 484             }
 485             break;
 486          case CIfnze:
 487             curpos->top = curpos->clmark;
 488          case CIfnznocls:
 489             if ( val1 )
 490             {
 491                curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 492                continue;
 493             }
 494             break;
 495          case CDwload:
 496          case CCmdload:
 497          case CResload:
 498             *curpos->top = *( curpos->cmd + 1 );
 499             break;
 500          case CQwload:
 501             *( pulong64 )curpos->top = *( pulong64 )( curpos->cmd + 1 );
 502             break;
 503          case CDwsload:
 504             val = *++curpos->cmd;
 505             while ( val-- )
 506                *curpos->top++ = *++curpos->cmd;
 507             break;
 508          case CVarload:
 509          case CVarptrload:
 510             i = *( curpos->cmd + 1 );
 511             if ( i < curpos->func->parcount )
 512             {
 513                pvar = curpos->func->params + i;
 514                top = curpos->start + pvar->off;
 515             }
 516             else
 517             {
 518                pvar = BCODE( curpos )->vars + ( i - curpos->func->parcount );
 519                top = ( puint )*( curpos->start + curpos->func->parsize ) +
 520                       pvar->off;
 521             }
 522             ptype = ( povmtype )PCMD( pvar->type );
 523 //            pvari = curpos->func->parvar + *( curpos->cmd + 1 ); 
 524 //            top = curpos->start + pvari->off;
 525             if ( cmd == CVarload && ptype->vmo.flag & GHTY_STACK ) 
 526             {
 527                *curpos->top = *top;
 528                if ( ptype->stsize > 1 )
 529                   *++curpos->top = *++top;
 530             }
 531             else
 532             {
 533                if ( pvar->flag & VAR_PARAM && //i < curpos->func->parcount && 
 534                     !( ptype->vmo.flag & GHTY_STACK ))
 535                   top = ( puint )*top; // For parameters
 536                *curpos->top = ( uint )top;
 537             }
 538 //            print("VARLOAD = ptr = %x %x off = %i %i\n", 
 539 //                      top, *top, pvar->off, i );
 540             break;
 541          case CDatasize:
 542             val = *++curpos->cmd;
 543             *curpos->top++ = ( uint )++curpos->cmd;
 544             // Увеличиваем на 3 : 2 вместо 1 : 0 из-за команда и размера
 545             curpos->cmd += ( val >> 2 ) + ( val & 3 ? 1 : 0 );
 546             *curpos->top++ = val;
 547             continue;
 548          case CLoglongtrue: *pop2 = ( val1 || val2 ? 1 : 0 );  break;
 549          case CLognot:      *pop1 = !val1; break;
 550          case CLoglongnot:  *pop2 = ( val1 || val2 ? 0 : 1 ); break;
 551          case CDup:         *curpos->top = *pop1; break;
 552          case CDuplong:
 553             *curpos->top = *pop2;
 554             *( curpos->top + 1 ) = *pop1;
 555             break;
 556          case CTop: *curpos->top = ( uint )( curpos->top ); break;
 557          case CPop: break;
 558          case CGetUB: *pop1 = *( pubyte )val1; break;
 559          case CGetB:  *( int *)pop1 = ( int )*( pchar )val1; break;
 560          case CGetUS: *pop1 = *( pushort )val1; break;
 561          case CGetS:  *( int *)pop1 = ( int )*( pshort )val1; break;
 562          case CGetI: *pop1 = *( puint )val1; break;
 563          case CGetL: *( pulong64 )pop1 = *( pulong64 )val1; break;
 564          case CSetUB: *( pubyte )val2 = ( ubyte )val1; goto set;
 565          case CSetB:  *( pchar )val2 = ( byte )val1; goto set;
 566          case CSetUS: *( pushort )val2 = ( ushort )val1; goto set;
 567          case CSetS:  *( pshort )val2 = ( short )val1; goto set;
 568          case CSetI:  *( puint )val2 = val1; goto set;
 569          case CSetL: 
 570             *( pulong64 )*( curpos->top - 3 ) = *( pulong64 )pop2;
 571             *( curpos->top - 3 ) = val2; 
 572             goto set;
 573          case CAddUIUI:  *pop2 += val1; break;
 574          case CSubUIUI:  *pop2 -= val1; break;
 575          case CMulUIUI:  *pop2 *= val1; break;
 576          case CDivUIUI:  *pop2 /= val1; break;
 577          case CModUIUI:  *pop2 %= val1; break;
 578          case CAndUIUI:  *pop2 &= val1; break;
 579          case COrUIUI:   *pop2 |= val1; break;
 580          case CXorUIUI:  *pop2 ^= val1; break;
 581          case CLeftUIUI: *pop2 <<= val1; break;
 582          case CRightUIUI:   *pop2 >>= val1; break;
 583          case CLessUIUI:    *pop2 = val2 < val1 ? 1 : 0; break;
 584          case CGreaterUIUI: *pop2 = val2 > val1 ? 1 : 0; break;
 585          case CEqUIUI:      *pop2 = val1 == val2 ? 1 : 0; break;
 586          case CNotUI:       *pop1 = ~val1; break;
 587          case CIncLeftUI:   *pop1 =  ++( *( puint )val1 ); break;
 588          case CIncRightUI:  *pop1 =  ( *( puint )val1 )++; break;
 589          case CDecLeftUI:   *pop1 =  --( *( puint )val1 ); break;
 590          case CDecRightUI:  *pop1 =  ( *( puint )val1 )--; break;
 591          case CAddUI:   *( puint )val2 += val1; goto setui;
 592          case CSubUI:   *( puint )val2 -= val1; goto setui;
 593          case CMulUI:   *( puint )val2 *= val1; goto setui;
 594          case CDivUI:   *( puint )val2 /= val1; goto setui;
 595          case CModUI:   *( puint )val2 %= val1; goto setui;
 596          case CAndUI:   *( puint )val2 &= val1; goto setui;
 597          case COrUI:    *( puint )val2 |= val1; goto setui;
 598          case CXorUI:   *( puint )val2 ^= val1; goto setui;
 599          case CLeftUI:  *( puint )val2 <<= val1; goto setui;
 600          case CRightUI: *( puint )val2 >>= val1; goto setui;
 601          case CVarsInit:  type_setinit( curpos, *( curpos->cmd + 1 )); break;
 602          case CGetText: *curpos->top = curpos->func->vmo.flag & GHBC_TEXT ? 
 603                              *( curpos->start - 1 ) : 0; break; 
 604          case CSetText: 
 605             if ( curpos->func->vmo.flag & GHBC_TEXT && 
 606                   ( val2 = *( curpos->start - 1 )) )
 607                str_add( ( pstr )val2, ( pstr )val1 );
 608             else
 609                str_output( ( pstr )val1 );
 610             break;
 611          case CPtrglobal:
 612             *curpos->top = ( uint )(( povmglobal )
 613                            PCMD( *( curpos->cmd + 1 )))->pval;
 614 //            print("Global PTR %x %i\n", *curpos->top, *( puint )*curpos->top );
 615             break;
 616          case CSubcall:
 617             // Меняем стэк 
 618             *curpos->top++ = ( uint )( curpos->cmd + 2 ); // указатель на команду после выхода
 619             *curpos->top++ = ( uint )curpos->clmark;  // текущее значение clmark 
 620             *curpos->top++ = 0;               // Количество возвращаемых dword 
 621             *curpos->top++ = 0;               // Количество полученных dword в качестве параметров
 622             curpos->clmark = curpos->top;     // Новое значение clmark
 623             // Указатель на первую команду подфункции
 624             curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );
 625             continue;
 626          case CSubret:
 627             *( curpos->clmark - 2 ) = *( curpos->cmd + 1 );
 628             break;
 629          case CSubpar:
 630             pset = BCODE( curpos )->sets + *( curpos->cmd + 1 );
 631             // копируем значения переменных из стэка
 632             pvar = BCODE( curpos )->vars + pset->first;
 633             top = ( puint )*( curpos->start + curpos->func->parsize ) + pvar->off;
 634 
 635 //            top = curpos->start + ( curpos->func->varb + *++curpos->cmd)->firstoff;
 636 //            curpos->cmd++;
 637 //            print("Top=%i %i\n", *top, *( top + 1 ));
 638             mem_copyui( top,  curpos->clmark - 4 - pset->size, pset->size );
 639             *( curpos->clmark - 1 ) = pset->size;
 640             break;
 641          case CSubreturn:
 642             // Выход из подфункции
 643             top = curpos->clmark - 4;  // Указатель на старый top 
 644             // Восстанавливаем команду
 645             curpos->cmd = ( puint )*top;
 646             curpos->clmark = ( puint )*( top + 1 );
 647             i = *( top + 2 );
 648             // записываем возвращаемое значение
 649             if ( i )
 650                mem_copyui( top - *( top + 3 ), curpos->top - i, i );
 651                // Устанавливаем стэк
 652             curpos->top = top + i - *( top + 3 );
 653             continue;
 654          case CCmdcall:
 655             // Берем из стэка код команды
 656             top = curpos->top - *++curpos->cmd - 1;
 657             cmd = *top;
 658             // Сдвигаем параметры вызова в стэке
 659             mem_copyui( top, top + 1, *curpos->cmd );
 660             // сразу устанавливаем указатель на следующую команду
 661             curpos->top--;
 662             goto stackcmd;
 663          case CCallstd:
 664             val1 = *++curpos->cmd;  // Флаги вызова
 665             val2 = *++curpos->cmd;  // Размер параметров
 666             top = curpos->top;
 667             for ( i = 0; i < val2; i++ )
 668             {
 669                val = *--top;
 670 #ifdef LINUX
 671     	         __asm__ ("push %0"::"d"(val));
 672 #else
 673    #if defined ( __GNUC__) || defined (__TINYC__)
 674                __asm__ ("push %0"::"d"(val));
 675    #else
 676                _asm {
 677                   push val
 678                }
 679    #endif
 680 #endif
 681             }  
 682             exfunc = ( pvoid )*--top;
 683 #ifdef LINUX
 684             __asm__ ("call *%0"::"m"(exfunc));
 685             __asm__ ("mov %%eax,%0":"m="(val));
 686             __asm__ ("mov %%edx,%0":"m="(valhi));
 687 #else
 688    #if defined (__GNUC__) 
 689   
 690             __asm__ ("call *%0"::"m"(exfunc));
 691             __asm__ ("mov %%eax,%0":"m="(val));
 692             __asm__ ("mov %%edx,%0":"m="(valhi));
 693   
 694    #elif  defined (__TINYC__)
 695             __asm__ ("call *%0"::"m"(exfunc));
 696             __asm__ ("mov %%eax,%0":"m"(val));
 697             __asm__ ("mov %%edx,%0":"m"(valhi));
 698    #else
 699             _asm {
 700                call exfunc
 701                mov  val,eax
 702                mov  valhi,edx
 703             }
 704    #endif
 705 #endif
 706 
 707 #ifdef LINUX
 708 #else
 709             if ( val1 )// & GHEX_CDECL )
 710 #endif
 711             {
 712                i = val2 << 2;
 713 #ifdef LINUX
 714                __asm__ ("add %0, %%esp"::"m"(i));
 715 #else
 716    #if defined ( __GNUC__) || defined (__TINYC__)
 717                __asm__ ("add %0, %%esp"::"m"(i));
 718    #else
 719                _asm {
 720                   add esp, i
 721                }
 722    #endif
 723 #endif
 724             }
 725 //          if ( (( psovmfunc )curfunc)->dwret )
 726             *top++ = val;
 727             curpos->top = top;
 728             break;
 729          case CReturn:
 730             if ( curpos == endpos )  // Все выполнили
 731                goto end;  
 732             // !!! Insert exception here
 733 /*               if ( vm->lastexcept->start == curpos->start )
 734                {
 735                   vm->lastexcept--;
 736                }*/
 737             if ( _gentee.debug )
 738                _gentee.debug( curpos ); 
 739 
 740             // Free all variables
 741             bcode = BCODE( curpos );
 742 
 743             if ( bcode->setcount )
 744             {
 745                for ( i = 0; i < bcode->setcount; i++ )
 746                   type_setdelete( curpos, i );
 747                // Освобождаем память под структуры
 748 //    ???      if ( *( curpos->start + pbcode->dwsize - 1 ))
 749                if ( bcode->varsize > VAR_SIZE )
 750                   mem_free( ( pvoid )*( curpos->start + curpos->func->parsize ));
 751             }
 752             // Возвращаемся в предыдущее состояние
 753             // если функция возвращает значение, то сохраняем необходимое 
 754             // количество верхних элементов
 755             if ( curpos->uiret )
 756             {
 757                mem_copyui( ( curpos + 1 )->top, curpos->top - curpos->uiret,
 758                            curpos->uiret );
 759                ( curpos + 1 )->top += curpos->uiret;
 760             }
 761             curpos++;
 762 /*            if ( exceptfunc )
 763                {
 764                   curpos->cmd = curpos->func->finally;
 765                   *curpos->top++ = 0;
 766                   *curpos->top++ = 0;
 767                   if ( curpos->start == exceptfunc ) 
 768                      exceptfunc = 0;
 769                   continue;
 770                }*/
 771             // cmdshift for CReturn == 1 - shift the calling command
 772             break;
 773 #ifndef RUNTIME
 774          case CDbgTrace:
 775          case CDbgFunc:
 776             if ( _gentee.debug )
 777             {
 778                curpos->nline = ( cmd == CDbgFunc ? *( puint )val2 : val1 ); 
 779                _gentee.debug( curpos );
 780             }
 781             break;
 782 #endif
 783       }
 784       goto shift;
 785 pseudo:   // Pseudo stack commands
 786       (( stackfunc )curfunc->func)( curpos );
 787       goto shift;
 788 set:
 789       *pop2 = val1; goto shift;
 790 setui:
 791       *pop2 = *( puint )val2; goto shift;
 792 
 793 shift:
 794       curpos->top += (( povmstack )curfunc)->topshift;
 795       curpos->cmd += (( povmstack )curfunc)->cmdshift;
 796       continue;
 797 //----------------   Bytecode command --------------------------------------
 798 bcode:
 799       // Проверка переполнения стэка
 800       if ( curpos->top + 128 > ( puint )curpos )
 801          msg( MFullstack | MSG_DVAL, _vm.stacksize );
 802       // Сохраняем текущее состояние увеличив стэк
 803       curpos->top -= curfunc->parsize;
 804       curpos--;
 805       curpos->cmd = curfunc->func;
 806       curpos->start = ( curpos + 1 )->top;
 807 
 808       curpos->top = curpos->start + curfunc->parsize + 1 + 
 809                    (( povmbcode )curfunc)->setcount;
 810       if ( (( povmbcode )curfunc)->varsize > VAR_SIZE )
 811       {
 812          // All variable ar in the extern memory
 813          ( puint )*( curpos->start + curfunc->parsize ) = mem_alloc( (( povmbcode )curfunc)->varsize << 2 );
 814       }
 815       else
 816       {  // All variables are in the stack
 817          ( puint )*( curpos->start + curfunc->parsize ) = curpos->top;
 818          curpos->top += (( povmbcode )curfunc)->varsize;
 819       }
 820       curpos->clmark = curpos->top;
 821       curpos->uiret = curfunc->dwret;
 822       curpos->func = curfunc;
 823       // Зануляем признак отведения памяти для локальных структур
 824 //      *( curpos->top - 1 ) = 0;
 825 
 826       // Зануляем признаки инициализации блоков переменных
 827       if ( (( povmbcode )curfunc)->setcount )
 828          mem_zeroui( curpos->start + curfunc->parsize + 1, 
 829                      (( povmbcode )curfunc)->setcount );
 830       if ( !curpos->cmd )
 831          msg( MUndefcmd | MSG_VALSTRERR, curfunc->vmo.name, cmd );
 832       continue;
 833 
 834 //----------------   Exfunc commands --------------------------------------
 835 exfunc:
 836       exfunc = curfunc->func;
 837       if ( !exfunc )
 838          msg( MUndefcmd | MSG_VALSTRERR, curfunc->vmo.name, cmd );
 839       top = curpos->top;
 840 
 841 #ifdef LINUX
 842 		if ( curfunc->vmobj.flag & GHEX_SYSCALL )
 843       {
 844          curpos->top = syscall( curfunc, top );
 845          goto next;
 846       }
 847 #endif
 848 //      print("PAR=%i parsize=%i ret=%i %s\n", curfunc->parcount,
 849 //              curfunc->parsize, curfunc->dwret, curfunc->vmo.name );
 850       for ( i = 0; i < curfunc->parsize; i++ )
 851       {
 852          val = *--top;
 853 #ifdef LINUX
 854       	__asm__ ("push %0"::"d"(val));
 855 #else
 856    #if defined (__GNUC__) || defined (__TINYC__)
 857       	__asm__ ("push %0"::"d"(val));
 858    #else
 859          _asm { push val }
 860    #endif
 861 #endif
 862       }
 863       if ( curfunc->vmo.flag & GHEX_FLOAT )
 864       {
 865          if ( curfunc->dwret == 1 )
 866          {
 867 #ifdef LINUX
 868             __asm__ ("call *%0"::"m"(exfunc));
 869            	__asm__ ("fstp %%st":"=m"(val));
 870 #else
 871    #if defined ( __GNUC__) || defined (__TINYC__)
 872             __asm__ ("call *%0"::"m"(exfunc));
 873             __asm__ ("fstp %%st":"=m"(val));
 874 
 875    #else
 876             _asm {
 877                call exfunc
 878                fstp dword ptr [val]
 879             }
 880    #endif
 881 #endif
 882          }
 883          else
 884          {
 885 #ifdef LINUX
 886             __asm__ ("call *%0"::"m"(exfunc));
 887 	         __asm__ ("fstp %%st":"=t"(d):"0"(d));
 888    		   //__asm__ ("fstp %0":"=r"(&d));
 889 #else
 890    #if defined (__GNUC__) 
 891             __asm__ ("call *%0"::"m"(exfunc));
 892 	         __asm__ ("fstp %%st":"=t"(d):"0"(d));
 893    	    //__asm__ ("fstp %0":"=r"(&d));
 894    #elif defined (__TINYC__)
 895             __asm__ ("call *%0"::"m"(exfunc));
 896             __asm__ ("fstp %%st":"m"(d):"0"(d));
 897    #else 
 898             _asm {
 899                call exfunc
 900 //             fstp qword ptr [d]
 901                fstp d
 902             }
 903    #endif
 904 #endif
 905             val = *(uint*)&d;
 906             valhi = *((uint*)&d + 1 );
 907          }
 908       }
 909       else
 910       {
 911 #ifdef LINUX
 912          //print( "\07exfunc=%x val=%x\n", exfunc, val );
 913          __asm__ ("call *%0"::"m"(exfunc));
 914          __asm__ ("mov %%eax,%0":"m="(val));
 915          __asm__ ("mov %%edx,%0":"m="(valhi));
 916 #else
 917    #if defined (__GNUC__) 
 918          __asm__ ("call *%0"::"m"(exfunc));
 919          __asm__ ("mov %%eax,%0":"m="(val));
 920          __asm__ ("mov %%edx,%0":"m="(valhi));
 921    #elif defined (__TINYC__)
 922          __asm__ ("call *%0"::"m"(exfunc));
 923          __asm__ ("mov %%eax,%0":"m"(val));
 924          __asm__ ("mov %%edx,%0":"m"(valhi));
 925    #else
 926          _asm {
 927             call exfunc
 928             mov  val,eax
 929             mov  valhi,edx
 930          }
 931    #endif
 932 #endif
 933       }
 934 #ifdef LINUX
 935 #else
 936       if ( curfunc->vmo.flag & GHEX_CDECL )
 937 #endif
 938       {
 939          i = curfunc->parsize << 2;
 940 #ifdef LINUX
 941          __asm__ ("add %0, %%esp"::"m"(i));
 942 #else
 943    #if defined (__GNUC__) || defined (__TINYC__)
 944          __asm__ ("add %0, %%esp"::"m"(i));
 945    #else
 946          _asm { add esp, i }
 947    #endif
 948 #endif
 949       }
 950       if ( curfunc->dwret )
 951          *top++ = val;
 952       if ( curfunc->dwret == 2 )
 953          *top++ = valhi;
 954       curpos->top = top;
 955       goto next;
 956 
 957 //----------------   Type command --------------------------------------
 958 type:
 959       *curpos->top++ = cmd;
 960       goto next;
 961 
 962 //----------------   Getting next command ------------------------------
 963 next:
 964       curpos->cmd++;
 965    }
 966 
 967 end:
 968 // Copy the result value
 969    if ( result )
 970       mem_copyui( result, curpos->top - uiret, uiret );
 971 // Free stack
 972    mem_free( stack );
 973 
 974    return 1;
 975 error:
 976    msg( MUnkbcode | MSG_DVAL, cmd );
 977    return 0;
 978 }
 979 
 980 //--------------------------------------------------------------------------
 981 
 982 uint  STDCALL vm_runone( uint id, uint first )
 983 {
 984    uint  ret;
 985    uint  size = _vm.stacksize;
 986 
 987    // Изменяем размеры стэка для функций вызываемых из виртуальной машины
 988    _vm.stacksize = 8192;
 989    vm_run( id, &first, &ret );
 990    _vm.stacksize = size;
 991    return ret;
 992 }
 993 
 994 //--------------------------------------------------------------------------
 995 
 996 uint  STDCALL vm_runtwo( uint id, uint first, uint second )
 997 {
 998    uint  ret;
 999    uint  size = _vm.stacksize;
1000    uint  params[4];
1001 
1002    // Изменяем размеры стэка для функций вызываемых из виртуальной машины
1003    _vm.stacksize = 8192;
1004    params[0] = first;
1005    params[1] = second;
1006    vm_run( id, ( puint )¶ms, &ret );
1007    _vm.stacksize = size;
1008    return ret;
1009 }
1010 
1011 /*-----------------------------------------------------------------------------
1012 ** Id: gentee_call F
1013 * 
1014 * Summary: Call the function from the bytecode. The bytecode should be 
1015            previously loaded with the $[gentee_load] or $[gentee_compile]
1016            functions. 
1017 *
1018 * Params: id - The identifier of the called object. Can be obtained by /
1019                $[gentee_getid] function.
1020           result - Pointer to the memory space, to which the result will be /
1021                    written. It can be the pointer to #b(uint), #b(long) or  /
1022                    #b(double).
1023           ... - Required parameters of the function. 
1024 *
1025 * Return: #lng/retf#
1026 *  
1027 -----------------------------------------------------------------------------*/
1028 
1029 uint  CDECLCALL gentee_call( uint id, puint result, ... )
1030 {
1031    uint        ok = 0;
1032    pvmfunc     curfunc;
1033    va_list     argptr;
1034    uint        i = 0;
1035    uint        params[ 64 ];
1036    uint        size = _vm.stacksize;
1037 
1038    _vm.stacksize = 0x8000; // 32KB
1039    va_start( argptr, result );
1040    
1041    curfunc = ( pvmfunc )PCMD( id );
1042    if ( curfunc->vmo.flag & GHRT_MAYCALL )
1043    {
1044       while ( i < curfunc->parsize )
1045          params[ i++ ] = va_arg( argptr, uint );
1046 
1047       ok = vm_run( id, ( puint )¶ms, result );
1048    }
1049    va_end( argptr );
1050    _vm.stacksize = size;
1051 
1052    return ok;
1053 }
1054 
1055 uint  STDCALL vm_calladdr( void )
1056 {
1057    return ( uint )&gentee_call;
1058 }
1059 
1060 //-----------------------------------------------------------------------------
Edit