EnglishРусский  

   ..

   cmdlist.c

   cmdlist.g

   cmdlist.h

   ge.h

   geasm.c

   geload.c

   gesave.c

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

  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: gesave 18.10.06 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov ( gentee )
 13 *
 14 * Summary: 
 15 * 
 16 ******************************************************************************/
 17 #ifndef RUNTIME
 18 
 19 #include "ge.h"
 20 #include "../genteeapi/gentee.h"
 21 #include "../vm/vmload.h"
 22 #include "../vm/vmres.h"
 23 #include "../common/crc.h"
 24 #include "../bytecode/bytecode.h"
 25 
 26 pbuf  gesave;
 27 uint  gesaveoff;
 28 puint gecodes;
 29 
 30 void STDCALL gesave_addubyte( uint val )
 31 {
 32    buf_appendch( gesave, ( ubyte )val );
 33 }
 34 
 35 void STDCALL gesave_adduint( uint val )
 36 {
 37 	buf_appenduint( gesave, val );
 38 }
 39 
 40 void STDCALL gesave_addushort( uint val )
 41 {
 42 	buf_appendushort( gesave, ( ushort )val );
 43 }
 44 
 45 void STDCALL gesave_add2uint( uint val1, uint val2 )
 46 {
 47    gesave_adduint( val1 );
 48    gesave_adduint( val2 );
 49 }
 50 
 51 void STDCALL gesave_addptr( pubyte data )
 52 {
 53    buf_append( gesave, data, mem_len( data ) + 1 );
 54 }
 55 
 56 void STDCALL gesave_adddata( pubyte data, uint size )
 57 {
 58    buf_append( gesave, data, size );
 59 }
 60 
 61 //--------------------------------------------------------------------------
 62 
 63 uint  STDCALL gesave_bwdi( uint val )
 64 {
 65    if ( val <= 187 )
 66       gesave_addubyte( val );
 67    else
 68       if ( val < 16830 ) // 0xFF *( 253 - 188 ) + 0xFF
 69       {
 70          gesave_addubyte( 188 + val / 0xFF );
 71          gesave_addubyte( val % 0xFF );
 72       }
 73       else
 74          if ( val > MAX_USHORT )
 75          {
 76             gesave_addubyte( MAX_BYTE );
 77             gesave_adduint( val );
 78          }
 79          else
 80          {
 81             gesave_addubyte( MAX_BYTE - 1 );
 82             gesave_addushort( val );
 83          }
 84    return val;
 85 }
 86 
 87 //--------------------------------------------------------------------------
 88 
 89 uint  STDCALL gesave_bwdc( uint val )
 90 {
 91    if ( val >= KERNEL_COUNT && !gecodes[ val ] )
 92    {
 93       print("GESAVE ERROR %i\n", val );
 94       os_getchar();
 95    }
 96    return gesave_bwdi( val >= KERNEL_COUNT ? gecodes[ val ] : val );
 97 }
 98 
 99 //--------------------------------------------------------------------------
100 
101 uint  STDCALL gesave_cmdflag( uint val )
102 {
103    uint flag = val & 0xFF000000;
104    val &= 0xFFFFFF;
105    if ( val >= KERNEL_COUNT )
106    {
107       if ( !gecodes[ val ] )
108       {
109          print("GESAVE ERROR %i\n", val );
110          os_getchar();
111       }
112       else
113          val = gecodes[ val ];
114    }
115    gesave_adduint( val | flag );
116    return val | flag;
117 }
118 
119 void STDCALL gesave_head( uint type, pubyte name, uint flag )
120 {
121    uint   ok = 0;
122    pubyte cur; 
123    gesaveoff = buf_len( gesave );
124 
125    flag &= 0xFFFFFF;
126 
127    if ( name && name[0] )
128       flag |= GHCOM_NAME;
129    else
130       flag &= ~GHCOM_NAME;
131    
132    if ( flag & GHCOM_NAME && _compile->flag & CMPL_OPTIMIZE &&
133               _compile->popti->flag & OPTI_NAME )
134    {
135       cur = _compile->popti->nameson;
136       while ( *cur )
137       {
138          if ( ptr_wildcardignore( name, cur ))
139          {
140             ok = 1;
141             break;
142          }
143          cur += mem_len( cur ) + 1;
144       }
145       if ( !ok )
146          flag &= ~GHCOM_NAME;
147    }
148    flag |= GHCOM_PACK;
149 
150    gesave_addubyte( type );
151    gesave_adduint( flag );
152    // The size will be inserted in gesave_finish
153    // Now add just one byte
154    gesave_addubyte( 0 );
155 
156    if ( flag & GHCOM_NAME )
157       gesave_addptr( name );
158 }
159 
160 void STDCALL gesave_finish( void )
161 {
162    buf  bt;
163    pbuf pb = gesave;
164    uint size = buf_len( pb ) - gesaveoff;
165 
166    if ( size <= 187 )
167       *( pubyte )(( pubyte )buf_ptr( gesave ) + gesaveoff + 5 ) = ( ubyte )size;
168    else
169    {
170       buf_init( &bt );
171       gesave = &bt;
172       if ( size < 16800 )
173       {
174          size++;
175          gesave_bwdi( size );
176       }
177       else
178          if ( size < 0xFFF0 ) 
179          {
180             gesave_addubyte( 0xFE );
181             size += 2;
182             gesave_addushort( size );
183          }
184          else
185          {
186             gesave_addubyte( 0xFF );
187             size += 4;
188             gesave_adduint( size );
189          }
190       // Write the size
191       // We have already had one byte, so -1
192       buf_insert( pb, gesaveoff + 5, ( pubyte )&size /*any*/, buf_len( gesave ) - 1 );
193       mem_copy( buf_ptr( pb ) + gesaveoff + 5, buf_ptr( gesave ), buf_len( gesave ));
194 
195       buf_delete( &bt );
196       gesave = pb;
197    }
198 }
199 
200 void STDCALL gesave_var( pvartype var )
201 {
202    uint      i;
203    povmtype  ptype;
204    pubyte    ptr;
205 
206    gesave_bwdc( var->type );
207 
208    if ( _compile->flag & CMPL_OPTIMIZE &&
209            _compile->popti->flag & OPTI_NAME )
210       var->flag &= ~VAR_NAME;
211 
212    gesave_addubyte( var->flag );
213 
214    if ( var->flag & VAR_NAME )
215       gesave_addptr( var->name );
216 
217    if ( var->flag & VAR_OFTYPE )
218       gesave_bwdc( var->oftype );
219 
220    if ( var->flag & VAR_DIM )
221    {
222       gesave_addubyte( var->dim );
223       for ( i = 0; i < var->dim; i++ )
224          gesave_bwdi( var->ptr[i] );
225    }
226    if ( var->flag & VAR_DATA )
227    {
228       ptr = ( pubyte )( var->ptr + var->dim );
229       ptype = ( povmtype )PCMD( var->type );
230       if ( ptype->vmo.flag & GHTY_STACK )
231          i = ptype->size;
232       else
233          if ( var->type == TStr )
234             i = mem_len( ptr ) + 1;
235          else
236          {
237             i = *( puint )ptr;
238             ptr += sizeof( uint );
239 //            gesave_adduint( i );
240             gesave_bwdi( i );   // save data size as bwd
241          }
242       gesave_adddata( ptr, i );
243    }
244 }
245 
246 void STDCALL gesave_varlist( pvartype pvar, uint count )
247 {
248    uint i;
249 
250    gesave_bwdi( count );
251    for ( i = 0; i < count; i++ )
252       gesave_var( pvar++ );
253 }
254 
255 void STDCALL gesave_resource( void )
256 {
257    uint     i, count;
258    pcollect pres;
259 
260    pres = &_vm.resource;
261 
262    gesave_head( OVM_RESOURCE, "", 0 );
263    
264    count = collect_count( pres );
265    gesave_bwdi( count );
266    for ( i = 0; i < count; i++ )
267    {
268       gesave_bwdc( collect_gettype( pres, i ));
269       gesave_addptr( str_ptr( vmres_getstr( i )) );
270 //      print("str=%s\n", str_ptr( vmres_getstr( i )) );
271    }
272    gesave_finish();
273 }
274 
275 void STDCALL gesave_bytecode( povmbcode bcode )
276 {
277    pvartype  pvar;
278    uint      i, count = 0, cmd, val, k;
279    puint     end, ptr;
280 
281    gesave_var( bcode->vmf.ret );
282    gesave_varlist( bcode->vmf.params, bcode->vmf.parcount );
283 
284    gesave_bwdi( bcode->setcount );
285    for ( i = 0; i < bcode->setcount; i++ )
286    {
287       gesave_bwdi( bcode->sets[i].count );
288       count += bcode->sets[i].count;
289    }
290    pvar = bcode->vars;
291    for ( i = 0; i < count; i++ )
292       gesave_var( pvar++ );
293 
294    ptr = ( puint )bcode->vmf.func;
295    if ( ptr )
296    {
297       end = ( puint )( ( pubyte )ptr + bcode->bcsize );
298       while ( ptr < end )
299       {
300          cmd = gesave_bwdc( *ptr++ );
301          if ( cmd >= CNop && cmd < CNop + STACK_COUNT )
302             switch ( cmd  )
303             {
304                case CQwload:
305                   gesave_adduint( *ptr++ );
306                   gesave_adduint( *ptr++ );
307                   break;
308                case CDwload:
309                   val = *ptr++;
310                   if ( val <= 0xFF )
311                   {
312                      buf_ptr( gesave )[ buf_len( gesave ) - 1 ] = CByload;
313                      gesave_addubyte( val );
314                   }
315                   else
316                      if ( val <= 0xFFFF )
317                      {
318                         buf_ptr( gesave )[ buf_len( gesave ) - 1 ] = CShload;
319                         gesave_addushort( val );
320                      }
321                      else
322                         gesave_adduint( val );
323                   break;
324                case CDwsload:
325                   i = gesave_bwdi( *ptr++ ); 
326                   for ( k = 0; k < i; k++ )
327                      gesave_cmdflag( *ptr++ );
328                   break;
329                case CAsm:
330                   i = gesave_bwdi( *ptr++ );
331                   gesave_adddata( ( pubyte )ptr, i << 2 );
332                   ptr += i;
333                   break;
334                case CResload:
335                case CCmdload:
336                case CPtrglobal:
337                   gesave_bwdc( *ptr++ );
338                   break;
339                case CDatasize:
340                   i = gesave_bwdi( *ptr++ );
341                   gesave_adddata( ( pubyte )ptr, i );
342                   ptr += ( i >> 2 ) + ( i & 3 ? 1 : 0 );
343                   break;
344                default:
345                   switch ( shifts[ cmd - CNop ] )
346                   {
347                      case SH1_3:
348                      case SH2_3:
349                         cmd = gesave_bwdi( *ptr++ );
350                      case SHN1_2:
351                      case SH0_2:
352                      case SH1_2:
353                         cmd = gesave_bwdi( *ptr++ );
354                         break;
355                   }
356             }
357       }
358    }
359 }
360 
361 void STDCALL gesave_exfunc( povmfunc exfunc )
362 {
363    gesave_var( exfunc->vmf.ret );
364    gesave_varlist( exfunc->vmf.params, exfunc->vmf.parcount );
365    
366    if ( exfunc->vmf.vmo.flag & GHEX_IMPORT )
367    {
368       gesave_bwdc( exfunc->import );
369       gesave_addptr( exfunc->original );
370    }
371 }
372 
373 void STDCALL gesave_import( povmimport import )
374 {
375    gesave_addptr( import->filename );
376    if ( import->vmo.flag & GHIMP_LINK )
377    {
378       gesave_adduint( import->size );
379       gesave_adddata( import->data, import->size );
380    }
381 }
382 
383 void STDCALL gesave_type( povmtype ptype )
384 {
385    uint      i, k;
386    uint      flag = ptype->vmo.flag;
387 
388    if ( flag & GHTY_INHERIT )
389       gesave_bwdc( ptype->inherit );
390 
391    if ( flag & GHTY_INDEX )
392    {
393       gesave_bwdc( ptype->index.type );
394       gesave_bwdc( ptype->index.oftype );
395    }
396    if ( flag & GHTY_INITDEL )
397    {
398       gesave_bwdc( ptype->ftype[ FTYPE_INIT ] );
399       gesave_bwdc( ptype->ftype[ FTYPE_DELETE ] );
400    }
401    if ( flag & GHTY_EXTFUNC )
402    {
403       gesave_bwdc( ptype->ftype[ FTYPE_OFTYPE ] );
404       gesave_bwdc( ptype->ftype[ FTYPE_COLLECTION ] );
405    }
406    if ( flag & GHTY_ARRAY )
407    {
408       i = 0;
409       while ( ptype->ftype[ FTYPE_ARRAY + i ] )
410          i++;
411       gesave_bwdc( i == 1 ? ptype->ftype[ FTYPE_ARRAY ] : i );
412       if ( i > 1 )
413          for ( k = 0; k < i; k++ )
414             gesave_bwdc( ptype->ftype[ FTYPE_ARRAY + k ] );
415    }
416    gesave_varlist( ptype->children, ptype->count );
417 }
418 
419 void STDCALL gesave_define( povmdefine pdefine )
420 {
421    gesave_varlist( pdefine->macros, pdefine->count );
422 }
423 
424 uint STDCALL ge_save( pbuf out )
425 {
426    gehead   head;
427    pgehead  phead;
428    uint     i, count, off = 0;
429    pvmobj   pvmo;
430    gesave = out;
431    buf_reserve( out, 0x1ffff );
432 
433    if ( _compile->flag & CMPL_OPTIMIZE )
434       ge_optimize();
435 
436    *( puint )&head.idname = GE_STRING;//0x00004547;   // строка GE
437    head.flags = 0;
438    head.crc = 0;
439    head.headsize = sizeof( gehead );
440    head.size = 0;
441    head.vermajor = GEVER_MAJOR; 
442    head.verminor = GEVER_MINOR; 
443    
444    buf_append( out, ( pubyte )&head, sizeof( gehead ));
445    // Save resources at the first !
446    gesave_resource();
447 
448    count = arr_count( &_vm.objtbl );
449    // Settings new id depending on GHRT_SKIP
450    gecodes = ( puint )mem_alloc( count * sizeof( uint ));
451    for ( i = KERNEL_COUNT; i < count ; i++ )
452    {
453       pvmo = ( pvmobj )PCMD( i );
454       if ( pvmo->flag & GHRT_SKIP )
455       {
456          gecodes[ i ] = 0;   
457          off++;
458       }
459       else
460          gecodes[ i ] = i - off;
461    }
462    for ( i = KERNEL_COUNT; i < count ; i++ )
463    {
464       pvmo = ( pvmobj )PCMD( i );
465       if ( pvmo->flag & GHRT_SKIP )
466          continue;
467 //      print("i=%i name=%s\n", i, ((pvmobj)PCMD( i ))->name );
468       gesave_head( pvmo->type, pvmo->flag & GHCOM_NAME ? 
469                 pvmo->name : NULL, pvmo->flag );
470 
471       switch ( pvmo->type )
472       {
473          case OVM_NONE:
474             break;
475          case OVM_BYTECODE:
476             gesave_bytecode( ( povmbcode )pvmo );
477             break;
478          case OVM_EXFUNC:
479             gesave_exfunc( ( povmfunc )pvmo );
480             break;
481          case OVM_TYPE:
482             gesave_type( ( povmtype )pvmo );
483             break;
484          case OVM_GLOBAL:
485             gesave_var( (( povmglobal )pvmo)->type );
486             break;
487          case OVM_DEFINE:
488             gesave_define( ( povmdefine )pvmo );
489             break;
490          case OVM_IMPORT:
491             gesave_import( ( povmimport )pvmo );
492             break;
493          case OVM_ALIAS:
494             gesave_bwdc( (( povmalias )pvmo)->idlink );
495             break;
496       }
497       gesave_finish();
498    }
499    mem_free( gecodes );
500    // Specify the full size and crc
501    phead = ( pgehead )buf_ptr( out );
502    phead->size = buf_len( out );
503    phead->crc = crc( ( pubyte )phead + 12, phead->size - 12, 0xFFFFFFFF );
504 
505    return 1;
506 }
507 
508 #endif
Редактировать