• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 25918451630

15 May 2026 12:43PM UTC coverage: 60.929% (+2.1%) from 58.859%
25918451630

push

github

turleypol
added dynamic property which returns a pointer of the object instead of
a copy like the current imp.
needed to be able to eg store a vector

43 of 61 new or added lines in 2 files covered. (70.49%)

14455 existing lines in 345 files now uncovered.

44695 of 73356 relevant lines covered (60.93%)

449621.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.76
/pol-core/bscript/eprog_read.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/12/07 MuadDib: Added "Recompile required" to Bad version reports.
5
 */
6

7
#include <cstdio>
8
#include <exception>
9
#include <map>
10
#include <string>
11

12
#include "../clib/logfacility.h"
13
#include "../clib/rawtypes.h"
14
#include "../clib/strutil.h"
15
#include "eprog.h"
16
#include "executor.h"
17
#include "filefmt.h"
18
#include "fmodule.h"
19
#include "modules.h"
20
#include "objmethods.h"
21
#include "symcont.h"
22
#include "token.h"
23
#include "tokens.h"
24

25

26
namespace Pol::Bscript
27
{
28
/**
29
 * Opens and ECL file containing bytecode and reads it
30
 *
31
 * This is where script bytecode processing is done
32
 */
33
int EScriptProgram::read( const char* fname )
2,143✔
34
{
35
  FILE* fp = nullptr;
2,143✔
36

37
  try
38
  {
39
    name = fname;
2,143✔
40

41
    fp = fopen( fname, "rb" );
2,143✔
42
    if ( !fp )
2,143✔
43
      throw std::runtime_error( std::string( "Unable to open " ) + fname + " for reading." );
1✔
44

45
    BSCRIPT_FILE_HDR hdr;
46
    if ( fread( &hdr, sizeof hdr, 1, fp ) != 1 )
2,142✔
47
    {
UNCOV
48
      ERROR_PRINTLN( "Error loading script {}: error reading header", fname );
×
49
      fclose( fp );
×
50
      return -1;
×
51
    }
52
    if ( hdr.magic2[0] != BSCRIPT_FILE_MAGIC0 || hdr.magic2[1] != BSCRIPT_FILE_MAGIC1 )
2,142✔
53
    {
UNCOV
54
      ERROR_PRINTLN( "Error loading script {}: bad magic value '{}{}'", fname, hdr.magic2[0],
×
55
                     hdr.magic2[1] );
UNCOV
56
      fclose( fp );
×
57
      return -1;
×
58
    }
59
    // auto-check for latest version (see filefmt.h for setting)
60
    if ( hdr.version != ESCRIPT_FILE_VER_CURRENT )
2,142✔
61
    {
UNCOV
62
      ERROR_PRINTLN( "Error loading script {}: Recompile required. Bad version number {}", fname,
×
63
                     hdr.version );
UNCOV
64
      fclose( fp );
×
65
      return -1;
×
66
    }
67
    version = hdr.version;
2,142✔
68
    nglobals = hdr.globals;
2,142✔
69
    BSCRIPT_SECTION_HDR sechdr;
70
    while ( fread( &sechdr, sizeof sechdr, 1, fp ) == 1 )
10,173✔
71
    {
72
      switch ( sechdr.type )
8,031✔
73
      {
74
      case BSCRIPT_SECTION_PROGDEF:
364✔
75
        if ( read_progdef_hdr( fp ) )
364✔
76
        {
UNCOV
77
          ERROR_PRINTLN( "Error loading script {}: error reading progdef section", fname );
×
78
          fclose( fp );
×
79
          return -1;
×
80
        }
81
        break;
364✔
82

83
      case BSCRIPT_SECTION_MODULE:
2,687✔
84
        if ( read_module( fp ) )
2,687✔
85
        {
UNCOV
86
          ERROR_PRINTLN( "Error loading script {}: error reading module section", fname );
×
87
          fclose( fp );
×
88
          return -1;
×
89
        }
90
        break;
2,687✔
91
      case BSCRIPT_SECTION_CODE:
2,142✔
92
        tokens.read( fp );
2,142✔
93
        break;
2,142✔
94
      case BSCRIPT_SECTION_SYMBOLS:
2,142✔
95
        symbols.read( fp );
2,142✔
96
        break;
2,142✔
UNCOV
97
      case BSCRIPT_SECTION_GLOBALVARNAMES:
×
98
        if ( read_globalvarnames( fp ) )
×
99
        {
UNCOV
100
          ERROR_PRINTLN( "Error loading script {}: error reading global variable name section",
×
101
                         fname );
UNCOV
102
          fclose( fp );
×
103
          return -1;
×
104
        }
UNCOV
105
        break;
×
106
      case BSCRIPT_SECTION_EXPORTED_FUNCTIONS:
105✔
107
        if ( read_exported_functions( fp, &sechdr ) )
105✔
108
        {
UNCOV
109
          ERROR_PRINTLN( "Error loading script {}: error reading exported functions section",
×
110
                         fname );
UNCOV
111
          fclose( fp );
×
112
          return -1;
×
113
        }
114
        break;
105✔
115
      case BSCRIPT_SECTION_FUNCTION_REFERENCES:
385✔
116
        if ( read_function_references( fp, &sechdr ) )
385✔
117
        {
UNCOV
118
          ERROR_PRINTLN( "Error loading script {}: error reading function references section",
×
119
                         fname );
UNCOV
120
          fclose( fp );
×
121
          return -1;
×
122
        }
123
        break;
385✔
124
      case BSCRIPT_SECTION_CLASS_TABLE:
206✔
125
        if ( read_class_table( fp ) )
206✔
126
        {
UNCOV
127
          ERROR_PRINTLN( "Error loading script {}: error reading class table section", fname );
×
128
          fclose( fp );
×
129
          return -1;
×
130
        }
131
        break;
206✔
UNCOV
132
      default:
×
133
        ERROR_PRINTLN( "Error loading script {}: unknown section type {}", fname, sechdr.type );
×
134
        fclose( fp );
×
135
        return -1;
×
136
      }
137
    }
138
    fclose( fp );
2,142✔
139

140
    return create_instructions();
2,142✔
141
  }
142
  catch ( std::exception& ex )
1✔
143
  {
144
    ERROR_PRINTLN( "Exception caught while loading script {}: {}", fname, ex.what() );
1✔
145
    if ( fp != nullptr )
1✔
UNCOV
146
      fclose( fp );
×
147
    return -1;
1✔
148
  }
1✔
149
#ifndef WIN32
UNCOV
150
  catch ( ... )
×
151
  {
UNCOV
152
    ERROR_PRINTLN( "Exception caught while loading script {}", fname );
×
153
    if ( fp != nullptr )
×
154
      fclose( fp );
×
155
    return -1;
×
156
  }
×
157
#endif
158
}
159
int EScriptProgram::create_instructions()
2,142✔
160
{
161
  int nLines = tokens.length() / sizeof( StoredToken );
2,142✔
162
  instr.resize( nLines );  // = new Instruction[ nLines ];
2,142✔
163

164
  for ( int i = 0; i < nLines; i++ )
164,308✔
165
  {
166
    Instruction& ins = instr[i];
162,166✔
167
    if ( _readToken( ins.token, i ) )
162,166✔
UNCOV
168
      return -1;
×
169

170
    // executor only:
171
    ins.func = Executor::GetInstrFunc( ins.token );
162,166✔
172
  }
173
  return 0;
2,142✔
174
}
175

176
/**
177
 * Reads the Program Header section from the file pointer
178
 */
179
int EScriptProgram::read_progdef_hdr( FILE* fp )
364✔
180
{
181
  BSCRIPT_PROGDEF_HDR hdr;
182
  if ( fread( &hdr, sizeof hdr, 1, fp ) != 1 )
364✔
UNCOV
183
    return -1;
×
184

185
  haveProgram = true;
364✔
186
  expectedArgs = hdr.expectedArgs;
364✔
187
  return 0;
364✔
188
}
189

190
/**
191
 * Reads a module "usages" section from the file pointer
192
 */
193
int EScriptProgram::read_module( FILE* fp )
2,687✔
194
{
195
  BSCRIPT_MODULE_HDR hdr;
196
  if ( fread( &hdr, sizeof hdr, 1, fp ) != 1 )
2,687✔
UNCOV
197
    return -1;
×
198
  auto fm = new FunctionalityModule( hdr.modulename );
2,687✔
199
  for ( unsigned i = 0; i < hdr.nfuncs; i++ )
6,263✔
200
  {
201
    BSCRIPT_MODULE_FUNCTION func;
202
    if ( fread( &func, sizeof func, 1, fp ) != 1 )
3,576✔
203
    {
UNCOV
204
      delete fm;
×
205
      return -1;
×
206
    }
207
    fm->addFunction( func.funcname, func.nargs );
3,576✔
208
  }
209
  modules.push_back( fm );
2,687✔
210
  return 0;
2,687✔
211
}
212

213
/* Note: This function is ONLY used from Executor::read(). */
214
int EScriptProgram::_readToken( Token& token, unsigned position ) const
162,166✔
215
{
216
  StoredToken st;
162,166✔
217
  tokens.atGet1( position, st );
162,166✔
218
  // StoredToken& st = tokens[position];
219

220
  token.module = (ModuleID)st.module;
162,166✔
221
  token.id = static_cast<BTokenId>( st.id );
162,166✔
222
  token.type = static_cast<BTokenType>( st.type );
162,166✔
223
  token.lval = st.offset;
162,166✔
224

225
  token.nulStr();
162,166✔
226

227
  // FIXME: USED to set lval to 0 for TYP_FUNC.  Not sure if needed anymore.
228
  // FIXME: Doesn't seem to be, but must be sure before removal
229
  switch ( st.id )
162,166✔
230
  {
231
  case INS_CASEJMP:
95✔
232
    if ( st.offset >= symbols.length() )
95✔
233
    {
UNCOV
234
      throw std::runtime_error(
×
235
          "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
236
          Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
237
    }
238
    token.dataptr = reinterpret_cast<const unsigned char*>( symbols.array() + st.offset );
95✔
239
    return 0;
95✔
240
  case TOK_LONG:
13,825✔
241
    if ( st.offset >= symbols.length() )
13,825✔
242
    {
UNCOV
243
      throw std::runtime_error(
×
244
          "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
245
          Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
246
    }
247
    std::memcpy( &token.lval, symbols.array() + st.offset, sizeof( int ) );
13,825✔
248
    return 0;
13,825✔
249
  case TOK_DOUBLE:
424✔
250
    if ( st.offset >= symbols.length() )
424✔
251
    {
UNCOV
252
      throw std::runtime_error(
×
253
          "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
254
          Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
255
    }
256
    std::memcpy( &token.dval, symbols.array() + st.offset, sizeof( double ) );
424✔
257
    return 0;
424✔
258

UNCOV
259
  case CTRL_STATEMENTBEGIN:
×
260
    if ( st.offset )
×
261
    {
UNCOV
262
      if ( st.offset >= symbols.length() )
×
263
      {
UNCOV
264
        throw std::runtime_error(
×
265
            "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
266
            Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
267
      }
UNCOV
268
      DebugToken* dt = (DebugToken*)( symbols.array() + st.offset );
×
269
      token.sourceFile = dt->sourceFile;
×
270
      token.lval = dt->offset;
×
271

UNCOV
272
      if ( dt->strOffset >= symbols.length() )
×
273
      {
UNCOV
274
        throw std::runtime_error( "Symbol offset of " + Clib::tostring( dt->strOffset ) +
×
275
                                  " exceeds symbol store length of " +
×
276
                                  Clib::tostring( symbols.length() ) +
×
277
                                  " at PC=" + Clib::tostring( position ) );
×
278
      }
UNCOV
279
      if ( dt->strOffset )
×
280
        token.setStr( symbols.array() + dt->strOffset );
×
281
    }
UNCOV
282
    return 0;
×
283

284
  case INS_INITFOREACH:
53,421✔
285
  case INS_STEPFOREACH:
286
  case INS_INITFOR:
287
  case INS_NEXTFOR:
288
  case TOK_GLOBALVAR:
289
  case TOK_LOCALVAR:
290
  case CTRL_JSR_USERFUNC:
291
  case CTRL_LEAVE_BLOCK:
292
  case TOK_ARRAY_SUBSCRIPT:
293
  case RSV_JMPIFFALSE:
294
  case RSV_JMPIFTRUE:
295
  case RSV_GOTO:
296
  case RSV_LOCAL:
297
  case RSV_GLOBAL:
298
  case INS_ASSIGN_GLOBALVAR:
299
  case INS_ASSIGN_LOCALVAR:
300
  case INS_GET_MEMBER_ID:
301
  case INS_SET_MEMBER_ID:
302
  case INS_SET_MEMBER_ID_CONSUME:
303
  case INS_CALL_METHOD_ID:
304
  case INS_CHECK_MRO:
305
  case INS_SET_MEMBER_ID_CONSUME_PLUSEQUAL:
306
  case INS_SET_MEMBER_ID_CONSUME_MINUSEQUAL:
307
  case INS_SET_MEMBER_ID_CONSUME_TIMESEQUAL:
308
  case INS_SET_MEMBER_ID_CONSUME_DIVIDEEQUAL:
309
  case INS_SET_MEMBER_ID_CONSUME_MODULUSEQUAL:
310
  case INS_SET_MEMBER_ID_UNPLUSPLUS:
311
  case INS_SET_MEMBER_ID_UNMINUSMINUS:
312
  case INS_SET_MEMBER_ID_UNPLUSPLUS_POST:
313
  case INS_SET_MEMBER_ID_UNMINUSMINUS_POST:
314
  case INS_SKIPIFTRUE_ELSE_CONSUME:
315
  case TOK_BOOL:
316
  case TOK_INTERPOLATE_STRING:
317
  case TOK_FUNCREF:
318
  case TOK_FUNCTOR:
319
  case TOK_SPREAD:
320
  case INS_TAKE_GLOBAL:
321
  case INS_TAKE_LOCAL:
322
  case INS_UNPACK_SEQUENCE:
323
  case INS_UNPACK_INDICES:
324
  case INS_LOGICAL_JUMP:
325
  case INS_LOGICAL_CONVERT:
326
    token.lval = st.offset;
53,421✔
327
    return 0;
53,421✔
328

329
  case INS_CALL_METHOD:
12,452✔
330
  case TOK_FUNC:
331
  case TOK_USERFUNC:
332
    token.lval = st.type;
12,452✔
333
    token.type = ( st.id == TOK_FUNC ) ? TYP_FUNC : TYP_USERFUNC;
12,452✔
334
    if ( st.offset )
12,452✔
335
    {
336
      if ( st.offset >= symbols.length() )
380✔
337
      {
338
        throw std::runtime_error(
×
339
            "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
UNCOV
340
            Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
341
      }
342
      token.setStr( symbols.array() + st.offset );
380✔
343
    }
344
    else if ( token.type == TYP_FUNC )
12,072✔
345
    {
346
      FunctionalityModule* modl = modules[token.module];
12,072✔
347
      const ModuleFunction* modfunc;
348

349
      // executor only:
350
      modfunc = modl->functions.at( token.lval );
12,072✔
351

352
      token.setStr( modfunc->name.get().c_str() );
12,072✔
353
    }
354
    return 0;
12,452✔
355

356
  default:
81,949✔
357
    if ( st.offset )
81,949✔
358
    {
359
      if ( st.offset >= symbols.length() )
32,343✔
360
      {
361
        throw std::runtime_error(
×
362
            "Symbol offset of " + Clib::tostring( st.offset ) + " exceeds symbol store length of " +
×
UNCOV
363
            Clib::tostring( symbols.length() ) + " at PC=" + Clib::tostring( position ) );
×
364
      }
365
      token.setStr( symbols.array() + st.offset );
32,343✔
366
    }
367
    return 0;
81,949✔
368
  }
369
}
370

UNCOV
371
int EScriptProgram::read_globalvarnames( FILE* fp )
×
372
{
373
  BSCRIPT_GLOBALVARNAMES_HDR hdr;
374
  if ( fread( &hdr, sizeof hdr, 1, fp ) != 1 )
×
375
    return -1;
×
376
  int res = 0;
×
377
  unsigned bufalloc = 20;
×
378
  auto buffer = new char[bufalloc];
×
UNCOV
379
  for ( unsigned idx = 0; idx < hdr.nGlobalVars; ++idx )
×
380
  {
381
    BSCRIPT_GLOBALVARNAME_HDR ghdr;
UNCOV
382
    if ( fread( &ghdr, sizeof ghdr, 1, fp ) != 1 )
×
383
    {
384
      res = -1;
×
UNCOV
385
      break;
×
386
    }
UNCOV
387
    if ( ghdr.namelen >= bufalloc )
×
388
    {
389
      bufalloc = ghdr.namelen + 5;
×
390
      delete[] buffer;
×
UNCOV
391
      buffer = new char[bufalloc];
×
392
    }
UNCOV
393
    if ( fread( buffer, ghdr.namelen + 1, 1, fp ) != 1 )
×
394
    {
395
      res = -1;
×
UNCOV
396
      break;
×
397
    }
UNCOV
398
    globalvarnames.emplace_back( buffer );
×
399
  }
400
  delete[] buffer;
×
401
  buffer = nullptr;
×
UNCOV
402
  return res;
×
403
}
404

405
int EScriptProgram::read_exported_functions( FILE* fp, BSCRIPT_SECTION_HDR* hdr )
105✔
406
{
407
  BSCRIPT_EXPORTED_FUNCTION bef;
408
  ObjMethod* mth;
409

410
  unsigned nexports = hdr->length / sizeof bef;
105✔
411
  while ( nexports-- )
449✔
412
  {
413
    if ( fread( &bef, sizeof bef, 1, fp ) != 1 )
344✔
UNCOV
414
      return -1;
×
415
    EPExportedFunction ef;
344✔
416
    ef.name = bef.funcname;
344✔
417
    ef.nargs = bef.nargs;
344✔
418
    ef.PC = bef.PC;
344✔
419
    exported_functions.push_back( ef );
344✔
420
    if ( ( mth = getKnownObjMethod( ef.name.c_str() ) ) != nullptr )
344✔
UNCOV
421
      mth->overridden = true;
×
422
  }
344✔
423
  return 0;
105✔
424
}
425

426
int EScriptProgram::read_function_references( FILE* fp, BSCRIPT_SECTION_HDR* hdr )
385✔
427
{
428
  BSCRIPT_FUNCTION_REFERENCE bfr;
429
  BSCRIPT_FUNCTION_REFERENCE_DEFAULT_PARAMETER bfrdp;
430

431
  unsigned nfuncrefs = hdr->length / sizeof bfr;
385✔
432
  while ( nfuncrefs-- )
1,941✔
433
  {
434
    if ( fread( &bfr, sizeof bfr, 1, fp ) != 1 )
1,556✔
UNCOV
435
      return -1;
×
436
    EPFunctionReference fr;
1,556✔
437
    fr.address = bfr.address;
1,556✔
438
    fr.parameter_count = bfr.parameter_count;
1,556✔
439
    fr.capture_count = bfr.capture_count;
1,556✔
440
    fr.is_variadic = bfr.is_variadic;
1,556✔
441
    fr.class_index = bfr.class_index;
1,556✔
442
    fr.is_constructor = bfr.is_constructor;
1,556✔
443

444
    auto default_parameter_count = bfr.default_parameter_count;
1,556✔
445

446
    while ( default_parameter_count-- )
1,743✔
447
    {
448
      if ( fread( &bfrdp, sizeof bfrdp, 1, fp ) != 1 )
187✔
UNCOV
449
        return -1;
×
450

451
      fr.default_parameter_addresses.push_back( bfrdp.address );
187✔
452
    }
453

454
    function_references.push_back( fr );
1,556✔
455
  }
1,556✔
456
  return 0;
385✔
457
}
458

459
int EScriptProgram::read_class_table( FILE* fp )
206✔
460
{
461
  BSCRIPT_CLASS_TABLE bct;
462
  if ( fread( &bct, sizeof bct, 1, fp ) != 1 )
206✔
UNCOV
463
    return -1;
×
464

465
  // For each class...
466
  while ( bct.class_count-- )
713✔
467
  {
468
    // Handle class
469
    BSCRIPT_CLASS_TABLE_ENTRY bcte;
470
    if ( fread( &bcte, sizeof bcte, 1, fp ) != 1 )
507✔
UNCOV
471
      return -1;
×
472

473
    // Handle constructors
474
    EPConstructorList constructors;
507✔
475
    constructors.reserve( bcte.constructor_count );
507✔
476

477
    while ( bcte.constructor_count-- )
1,206✔
478
    {
479
      BSCRIPT_CLASS_TABLE_CONSTRUCTOR_ENTRY bctce;
480
      if ( fread( &bctce, sizeof bctce, 1, fp ) != 1 )
699✔
UNCOV
481
        return -1;
×
482
      constructors.push_back( EPConstructorDescriptor{ bctce.type_tag_offset } );
699✔
483
    }
484

485
    // Handle methods
486
    EPMethodMap methods;
507✔
487
    while ( bcte.method_count-- )
828✔
488
    {
489
      BSCRIPT_CLASS_TABLE_METHOD_ENTRY bctme;
490
      if ( fread( &bctme, sizeof bctme, 1, fp ) != 1 )
321✔
UNCOV
491
        return -1;
×
492

493
      methods[bctme.name_offset] = EPMethodDescriptor{ bctme.function_reference_index };
321✔
494
    }
495

496
    class_descriptors.push_back(
1,014✔
497
        EPClassDescriptor{ bcte.name_offset, bcte.constructor_function_reference_index,
1,014✔
498
                           std::move( constructors ), std::move( methods ) } );
1,014✔
499
  }
507✔
500
  return 0;
206✔
501
}
502

503
int EScriptProgram::read_dbg_file( bool quiet )
47✔
504
{
505
  if ( debug_loaded )
47✔
506
    return 0;
38✔
507

508
  std::string mname = name;
9✔
509
  mname.replace( mname.size() - 3, 3, "dbg" );
9✔
510
  FILE* fp = fopen( mname.c_str(), "rb" );
9✔
511
  if ( !fp )
9✔
512
  {
513
    if ( !quiet )
2✔
UNCOV
514
      ERROR_PRINTLN( "Unable to open {}", mname );
×
515
    return -1;
2✔
516
  }
517

518
  u32 dbgversion;
519
  size_t fread_res = fread( &dbgversion, sizeof dbgversion, 1, fp );
7✔
520
  if ( fread_res != 1 || ( dbgversion != 2 && dbgversion != 3 ) )
7✔
521
  {
UNCOV
522
    ERROR_PRINTLN( "Recompile required. Bad version {} in {}, expected version 2", dbgversion,
×
523
                   mname );
524
    fclose( fp );
×
UNCOV
525
    return -1;
×
526
  }
527

528
  size_t bufalloc = 20;
7✔
529
  auto buffer = std::unique_ptr<char[]>( new char[bufalloc] );
7✔
530
  int res = 0;
7✔
531

532
  u32 count;
533
  fread_res = fread( &count, sizeof count, 1, fp );
7✔
534
  if ( fread_res != 1 )
7✔
535
  {
536
    fclose( fp );
×
UNCOV
537
    return -1;
×
538
  }
539
  dbg_filenames.resize( count );
7✔
540
  for ( auto& elem : dbg_filenames )
83✔
541
  {
542
    fread_res = fread( &count, sizeof count, 1, fp );
76✔
543
    if ( fread_res != 1 )
76✔
544
    {
545
      fclose( fp );
×
UNCOV
546
      return -1;
×
547
    }
548
    if ( count >= bufalloc )
76✔
549
    {
550
      bufalloc = count * 2;
7✔
551
      buffer.reset( new char[bufalloc] );
7✔
552
    }
553
    fread_res = fread( buffer.get(), count, 1, fp );
76✔
554
    if ( fread_res != 1 )
76✔
555
    {
556
      fclose( fp );
×
UNCOV
557
      return -1;
×
558
    }
559
    elem = buffer.get();
76✔
560
  }
561

562
  fread_res = fread( &count, sizeof count, 1, fp );
7✔
563
  if ( fread_res != 1 )
7✔
564
  {
565
    fclose( fp );
×
UNCOV
566
    return -1;
×
567
  }
568
  globalvarnames.resize( count );
7✔
569
  for ( auto& elem : globalvarnames )
29✔
570
  {
571
    fread_res = fread( &count, sizeof count, 1, fp );
22✔
572
    if ( fread_res != 1 )
22✔
573
    {
574
      fclose( fp );
×
UNCOV
575
      return -1;
×
576
    }
577
    if ( count >= bufalloc )
22✔
578
    {
579
      bufalloc = count * 2;
×
UNCOV
580
      buffer.reset( new char[bufalloc] );
×
581
    }
582
    fread_res = fread( buffer.get(), count, 1, fp );
22✔
583
    if ( fread_res != 1 )
22✔
584
    {
585
      fclose( fp );
×
UNCOV
586
      return -1;
×
587
    }
588
    elem = buffer.get();
22✔
589
  }
590

591
  fread_res = fread( &count, sizeof count, 1, fp );
7✔
592
  if ( fread_res != 1 )
7✔
593
  {
594
    fclose( fp );
×
UNCOV
595
    return -1;
×
596
  }
597
  dbg_filenum.resize( count );
7✔
598
  dbg_linenum.resize( count );
7✔
599
  dbg_ins_blocks.resize( count );
7✔
600
  dbg_ins_statementbegin.resize( count );
7✔
601
  for ( unsigned i = 0; i < tokens.count(); ++i )
8,836✔
602
  {
603
    BSCRIPT_DBG_INSTRUCTION ins;
604
    fread_res = fread( &ins, sizeof ins, 1, fp );
8,829✔
605
    if ( fread_res != 1 )
8,829✔
606
    {
607
      fclose( fp );
×
UNCOV
608
      return -1;
×
609
    }
610
    dbg_filenum[i] = ins.filenum;
8,829✔
611
    dbg_linenum[i] = ins.linenum;
8,829✔
612
    dbg_ins_blocks[i] = ins.blocknum;
8,829✔
613
    dbg_ins_statementbegin[i] = ins.statementbegin ? true : false;
8,829✔
614
  }
615
  fread_res = fread( &count, sizeof count, 1, fp );
7✔
616
  if ( fread_res != 1 )
7✔
617
  {
618
    fclose( fp );
×
UNCOV
619
    return -1;
×
620
  }
621
  blocks.resize( count );
7✔
622
  for ( auto& block : blocks )
190✔
623
  {
624
    u32 tmp;
625

626
    fread_res = fread( &tmp, sizeof tmp, 1, fp );
183✔
627
    if ( fread_res != 1 )
183✔
628
    {
629
      fclose( fp );
×
UNCOV
630
      return -1;
×
631
    }
632
    block.parentblockidx = tmp;
183✔
633

634
    fread_res = fread( &tmp, sizeof tmp, 1, fp );
183✔
635
    if ( fread_res != 1 )
183✔
636
    {
637
      fclose( fp );
×
UNCOV
638
      return -1;
×
639
    }
640
    block.parentvariables = tmp;
183✔
641

642
    fread_res = fread( &tmp, sizeof tmp, 1, fp );
183✔
643
    if ( fread_res != 1 )
183✔
644
    {
645
      fclose( fp );
×
UNCOV
646
      return -1;
×
647
    }
648
    block.localvarnames.resize( tmp );
183✔
649

650
    for ( auto& elem : block.localvarnames )
684✔
651
    {
652
      fread_res = fread( &count, sizeof count, 1, fp );
501✔
653
      if ( fread_res != 1 )
501✔
654
      {
655
        fclose( fp );
×
UNCOV
656
        return -1;
×
657
      }
658
      if ( count >= bufalloc )
501✔
659
      {
660
        bufalloc = count * 2;
×
UNCOV
661
        buffer.reset( new char[bufalloc] );
×
662
      }
663
      fread_res = fread( buffer.get(), count, 1, fp );
501✔
664
      if ( fread_res != 1 )
501✔
665
      {
666
        fclose( fp );
×
UNCOV
667
        return -1;
×
668
      }
669
      elem = buffer.get();
501✔
670
    }
671
  }
672
  if ( dbgversion >= 3 )
7✔
673
  {
674
    fread_res = fread( &count, sizeof count, 1, fp );
7✔
675
    if ( fread_res != 1 )
7✔
676
    {
677
      fclose( fp );
×
UNCOV
678
      return -1;
×
679
    }
680
    dbg_functions.resize( count );
7✔
681
    for ( auto& func : dbg_functions )
122✔
682
    {
683
      u32 tmp;
684
      fread_res = fread( &tmp, sizeof tmp, 1, fp );
115✔
685
      if ( fread_res != 1 )
115✔
686
      {
687
        fclose( fp );
×
UNCOV
688
        return -1;
×
689
      }
690
      if ( tmp >= bufalloc )
115✔
691
      {
692
        bufalloc = tmp * 2;
×
UNCOV
693
        buffer.reset( new char[bufalloc] );
×
694
      }
695
      fread_res = fread( buffer.get(), tmp, 1, fp );
115✔
696
      if ( fread_res != 1 )
115✔
697
      {
698
        fclose( fp );
×
UNCOV
699
        return -1;
×
700
      }
701
      func.name = buffer.get();
115✔
702

703
      fread_res = fread( &tmp, sizeof tmp, 1, fp );
115✔
704
      if ( fread_res != 1 )
115✔
705
      {
706
        fclose( fp );
×
UNCOV
707
        return -1;
×
708
      }
709
      func.firstPC = tmp;
115✔
710
      fread_res = fread( &tmp, sizeof tmp, 1, fp );
115✔
711
      if ( fread_res != 1 )
115✔
712
      {
713
        fclose( fp );
×
UNCOV
714
        return -1;
×
715
      }
716
      func.lastPC = tmp;
115✔
717
    }
718
  }
719

720
  fclose( fp );
7✔
721
  debug_loaded = true;
7✔
722
  return res;
7✔
723
}
9✔
724
}  // namespace Pol::Bscript
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc