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

polserver / polserver / 16683711876

01 Aug 2025 07:40PM UTC coverage: 59.756% (-0.03%) from 59.79%
16683711876

push

github

web-flow
use c++20 (#799)

* use c++20
* increased used clang version
* compiler report and logfacility use now compile time formatting, which
means that the formatstring gets checked at compile time. (which found 2 errors)
adapted a few places since report only accepts formatting arguments
adapted a few places with logging since char[] is compile time
formatting and string or chr* is runtime formatting
* use std::ranges instead of boost
* disabled pragma_assume vs specific macro (I guess noone cares)
* needed to fix ancient ms exception code
* modernized SpinLock
* removed unused code in ECompile
* replaced std::filesystem::path::u8string with string. It now returns an actual u8string type
* cleanup layers.h added the defines for other layers which where before
  only defined in the pkt
* osmod::OpenConnection and HTTPRequest cleanup: early outs, dont check for pChild which is
  only needed for startscript and placed suspend at the very last
  position

* fix warning

* rebuild cache with new compiler version

* define c++ standard for external libs where possible

* added fixme

156 of 212 new or added lines in 26 files covered. (73.58%)

45 existing lines in 19 files now uncovered.

43621 of 72999 relevant lines covered (59.76%)

409874.73 hits per line

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

87.37
/pol-core/bscript/compiler/format/StoredTokenDecoder.cpp
1
#include "StoredTokenDecoder.h"
2

3
#include "StoredToken.h"
4
#include "bscript/compiler/representation/DebugStore.h"
5
#include "bscript/compiler/representation/ModuleDescriptor.h"
6
#include "bscript/compiler/representation/ModuleFunctionDescriptor.h"
7
#include "objmembers.h"
8
#include "objmethods.h"
9
#include <algorithm>
10
#include <iterator>
11

12
namespace Pol::Bscript::Compiler
13
{
14
StoredTokenDecoder::StoredTokenDecoder( const std::vector<ModuleDescriptor>& module_descriptors,
1,851✔
15
                                        const std::vector<std::byte>& data )
1,851✔
16
    : module_descriptors( module_descriptors ), data( data )
1,851✔
17
{
18
}
1,851✔
19

20
void StoredTokenDecoder::decode_to( const StoredToken& tkn, std::string& w )
104,558✔
21
{
22
  switch ( tkn.id )
104,558✔
23
  {
24
  case TOK_LONG:
8,435✔
25
    fmt::format_to( std::back_inserter( w ), "{} (integer) offset={:#x}", integer_at( tkn.offset ),
8,435✔
26
                    tkn.offset );
8,435✔
27
    break;
8,435✔
28
  case TOK_DOUBLE:
384✔
29
    fmt::format_to( std::back_inserter( w ), "{} (float) offset={:#x}", double_at( tkn.offset ),
384✔
30
                    tkn.offset );
384✔
31
    break;
384✔
32
  case TOK_STRING:
17,661✔
33
  {
34
    auto s = string_at( tkn.offset );
17,661✔
35
    fmt::format_to( std::back_inserter( w ), "{} (string) len={} offset={:#x}",
17,661✔
36
                    Clib::getencodedquotedstring( s ), s.length(), tkn.offset );
35,322✔
37
    break;
17,661✔
38
  }
17,661✔
39
  case TOK_BOOL:
125✔
40
    fmt::format_to( std::back_inserter( w ), "{} (boolean)", static_cast<bool>( tkn.offset ) );
125✔
41
    break;
125✔
42
  case TOK_ADD:
2,109✔
43
    w += "+";
2,109✔
44
    break;
2,109✔
45
  case TOK_SUBTRACT:
318✔
46
    w += "-";
318✔
47
    break;
318✔
48
  case TOK_MULT:
198✔
49
    w += "*";
198✔
50
    break;
198✔
51
  case TOK_DIV:
51✔
52
    w += "/";
51✔
53
    break;
51✔
54

55
  case TOK_ASSIGN:
2,540✔
56
    w += ":=";
2,540✔
57
    break;
2,540✔
58
  case INS_ASSIGN_CONSUME:
63✔
59
    w += ":= #";
63✔
60
    break;
63✔
61

62
  case TOK_PLUSEQUAL:
69✔
63
    w += "+=";
69✔
64
    break;
69✔
65
  case TOK_MINUSEQUAL:
27✔
66
    w += "-=";
27✔
67
    break;
27✔
68
  case TOK_TIMESEQUAL:
18✔
69
    w += "*=";
18✔
70
    break;
18✔
71
  case TOK_DIVIDEEQUAL:
15✔
72
    w += "/=";
15✔
73
    break;
15✔
74
  case TOK_MODULUSEQUAL:
18✔
75
    w += "%=";
18✔
76
    break;
18✔
77
  case TOK_INSERTINTO:
2,871✔
78
    w += "append-array-element (TOK_INSERTINTO)";
2,871✔
79
    break;
2,871✔
80

81
  case TOK_LESSTHAN:
165✔
82
    w += "<";
165✔
83
    break;
165✔
84
  case TOK_LESSEQ:
66✔
85
    w += "<=";
66✔
86
    break;
66✔
87
  case TOK_GRTHAN:
129✔
88
    w += ">";
129✔
89
    break;
129✔
90
  case TOK_GREQ:
78✔
91
    w += ">=";
78✔
92
    break;
78✔
93

94
  case TOK_IS:
51✔
95
    w += "is";
51✔
96
    break;
51✔
97

98
  case TOK_AND:
16✔
99
    w += "&& (logical and)";
16✔
100
    break;
16✔
101
  case TOK_OR:
59✔
102
    w += "|| (logical or)";
59✔
103
    break;
59✔
104

105
    // equalite/inequality operators */
106
  case TOK_EQUAL:
726✔
107
    w += "==";
726✔
108
    break;
726✔
109
  case TOK_NEQ:
87✔
110
    w += "!=";
87✔
111
    break;
87✔
112

113
  case TOK_UNPLUS:
×
114
    w += "unary +";
×
115
    break;
×
116
  case TOK_UNMINUS:
3✔
117
    w += "unary -";
3✔
118
    break;
3✔
119
  case TOK_LOG_NOT:
72✔
120
    w += "! (logical inversion)";
72✔
121
    break;
72✔
122
  case TOK_BITWISE_NOT:
12✔
123
    w += "~ (bitwise inversion)";
12✔
124
    break;
12✔
125

126
  case TOK_CONSUMER:
14,187✔
127
    w += "# (consume)";
14,187✔
128
    break;
14,187✔
129

130
  case TOK_ARRAY_SUBSCRIPT:
576✔
131
    w += "TOK_ARRAY_SUBSCRIPT";
576✔
132
    break;
576✔
133

134
  case TOK_ADDMEMBER:
96✔
135
    w += ".+ (add-member)";
96✔
136
    break;
96✔
137
  case TOK_DELMEMBER:
9✔
138
    w += ".- (delete-member)";
9✔
139
    break;
9✔
140
  case TOK_CHKMEMBER:
72✔
141
    w += ".? (check-member)";
72✔
142
    break;
72✔
143

144
  case CTRL_STATEMENTBEGIN:
×
145
  {
146
    const Pol::Bscript::DebugToken& debug_token = debug_token_at( tkn.offset );
×
147

148
    fmt::format_to( std::back_inserter( w ), "CTRL_STATEMENTBEGIN sourceFile={} x={} y={}",
×
149
                    debug_token.sourceFile, debug_token.offset,
×
150
                    string_at( debug_token.strOffset ) );
×
151
    break;
×
152
  }
153
  case CTRL_PROGEND:
1,866✔
154
    w += "progend";
1,866✔
155
    break;
1,866✔
156
  case CTRL_MAKELOCAL:
1,943✔
157
    w += "makelocal";
1,943✔
158
    break;
1,943✔
159
  case INS_CHECK_MRO:
201✔
160
    fmt::format_to( std::back_inserter( w ), "check mro (this @ offset {})", tkn.offset );
201✔
161
    break;
201✔
162
  case CTRL_JSR_USERFUNC:
1,943✔
163
    fmt::format_to( std::back_inserter( w ), "jsr userfunc @{}", tkn.offset );
1,943✔
164
    break;
1,943✔
165
  case INS_POP_PARAM:
2,022✔
166
    fmt::format_to( std::back_inserter( w ), "pop param '{}'", string_at( tkn.offset ) );
4,044✔
167
    break;
2,022✔
168
  case CTRL_LEAVE_BLOCK:
852✔
169
    fmt::format_to( std::back_inserter( w ), "leave block (remove {} locals)", tkn.offset );
852✔
170
    break;
852✔
171

172
  case RSV_JMPIFFALSE:
975✔
173
    fmt::format_to( std::back_inserter( w ), "if false goto {}", tkn.offset );
975✔
174
    break;
975✔
175
  case RSV_JMPIFTRUE:
123✔
176
    fmt::format_to( std::back_inserter( w ), "if true goto {}", tkn.offset );
123✔
177
    break;
123✔
178
  case RSV_GOTO:
1,141✔
179
    fmt::format_to( std::back_inserter( w ), "goto {}", tkn.offset );
1,141✔
180
    break;
1,141✔
181
  case RSV_RETURN:
2,195✔
182
    w += "return";
2,195✔
183
    break;
2,195✔
184
  case RSV_EXIT:
18✔
185
    w += "exit";
18✔
186
    break;
18✔
187

188
  case RSV_LOCAL:
1,077✔
189
    fmt::format_to( std::back_inserter( w ), "declare local #{}", tkn.offset );
1,077✔
190
    break;
1,077✔
191
  case RSV_GLOBAL:
1,871✔
192
    fmt::format_to( std::back_inserter( w ), "declare global #{}", tkn.offset );
1,871✔
193
    break;
1,871✔
194

195
  case INS_TAKE_LOCAL:
261✔
196
    fmt::format_to( std::back_inserter( w ), "take local #{}", tkn.offset );
261✔
197
    break;
261✔
198

199
  case INS_TAKE_GLOBAL:
183✔
200
    fmt::format_to( std::back_inserter( w ), "take global #{}", tkn.offset );
183✔
201
    break;
183✔
202

203
  case INS_DECLARE_ARRAY:
69✔
204
    w += "declare array";
69✔
205
    break;
69✔
206

207
  case TOK_FUNC:
9,306✔
208
  {
209
    unsigned module_id = tkn.module;
9,306✔
210
    unsigned function_index = tkn.type;
9,306✔
211
    fmt::format_to( std::back_inserter( w ), "call module function ({}, {}): ", module_id,
9,306✔
212
                    function_index );
213
    if ( module_id >= module_descriptors.size() )
9,306✔
214
    {
215
      fmt::format_to( std::back_inserter( w ), "module index {} exceeds module_descriptors size {}",
×
216
                      module_id, module_descriptors.size() );
×
217
      break;
×
218
    }
219
    auto& module = module_descriptors.at( module_id );
9,306✔
220
    if ( function_index >= module.functions.size() )
9,306✔
221
    {
222
      fmt::format_to( std::back_inserter( w ), "function index {} exceeds module.functions size {}",
×
223
                      function_index, module.functions.size() );
×
224
      break;
×
225
    }
226
    auto& defn = module.functions.at( function_index );
9,306✔
227
    fmt::format_to( std::back_inserter( w ), "{}", defn.name );
9,306✔
228
    break;
9,306✔
229
  }
230
  case TOK_ERROR:
45✔
231
    w += "error";
45✔
232
    break;
45✔
233

234
  case TOK_LOCALVAR:
8,514✔
235
    fmt::format_to( std::back_inserter( w ), "local variable #{}", tkn.offset );
8,514✔
236
    break;
8,514✔
237
  case TOK_GLOBALVAR:
6,160✔
238
    fmt::format_to( std::back_inserter( w ), "global variable #{}", tkn.offset );
6,160✔
239
    break;
6,160✔
240

241
  case INS_INITFOREACH:
270✔
242
    fmt::format_to( std::back_inserter( w ), "initforeach @{}", tkn.offset );
270✔
243
    break;
270✔
244
  case INS_STEPFOREACH:
270✔
245
    fmt::format_to( std::back_inserter( w ), "stepforeach @{}", tkn.offset );
270✔
246
    break;
270✔
247
  case INS_CASEJMP:
87✔
248
  {
249
    w += "casejmp";
87✔
250
    decode_casejmp_table( w, tkn.offset );
87✔
251
    break;
87✔
252
  }
253
  case INS_GET_ARG:
42✔
254
    fmt::format_to( std::back_inserter( w ), "get arg '{}'", string_at( tkn.offset ) );
84✔
255
    break;
42✔
256
  case TOK_ARRAY:
1,305✔
257
    w += "create-array (TOK_ARRAY)";
1,305✔
258
    break;
1,305✔
259

260
  case INS_CALL_METHOD:
207✔
261
    fmt::format_to( std::back_inserter( w ), "call method '{}'", string_at( tkn.offset ) );
414✔
262
    break;
207✔
263

264
  case TOK_DICTIONARY:
150✔
265
    w += "TOK_DICTIONARY";
150✔
266
    break;
150✔
267
  case INS_INITFOR:
39✔
268
    fmt::format_to( std::back_inserter( w ), "initfor @{}", tkn.offset );
39✔
269
    break;
39✔
270
  case INS_NEXTFOR:
39✔
271
    fmt::format_to( std::back_inserter( w ), "nextfor @{}", tkn.offset );
39✔
272
    break;
39✔
273
  case INS_POP_PARAM_BYREF:
1,023✔
274
    fmt::format_to( std::back_inserter( w ), "pop param byref '{}'", string_at( tkn.offset ) );
2,046✔
275
    break;
1,023✔
276
  case TOK_MODULUS:
30✔
277
    w += "modulus";
30✔
278
    break;
30✔
279

280
  case TOK_BSLEFT:
15✔
281
    w += "<<";  // bitshift-left-sift";
15✔
282
    break;
15✔
283
  case TOK_BSRIGHT:
15✔
284
    w += ">>";  // bitshift-right-shift";
15✔
285
    break;
15✔
286
  case TOK_BITAND:
15✔
287
    w += "&";  // bitwise-and";
15✔
288
    break;
15✔
289
  case TOK_BITOR:
15✔
290
    w += "|";  // bitwise-or";
15✔
291
    break;
15✔
292
  case TOK_BITXOR:
15✔
293
    w += "^";  // bitwise-xor";
15✔
294
    break;
15✔
295

296
  case TOK_STRUCT:
300✔
297
    w += "create empty struct";
300✔
298
    break;
300✔
299
  case TOK_CLASSINST:
168✔
300
    fmt::format_to( std::back_inserter( w ), "create class instance (index={})", tkn.offset );
168✔
301
    break;
168✔
302
  case INS_SUBSCRIPT_ASSIGN:
3✔
303
    w += "subscript assign";
3✔
304
    break;
3✔
305
  case INS_SUBSCRIPT_ASSIGN_CONSUME:
423✔
306
    w += "subscript assign and consume";
423✔
307
    break;
423✔
308
  case INS_MULTISUBSCRIPT:
165✔
309
    fmt::format_to( std::back_inserter( w ), "multi subscript get ({} indexes)", tkn.offset );
165✔
310
    break;
165✔
311
  case INS_MULTISUBSCRIPT_ASSIGN:
6✔
312
    fmt::format_to( std::back_inserter( w ), "multi subscript assign ({} indexes)", tkn.offset );
6✔
313
    break;
6✔
314
  case INS_ASSIGN_LOCALVAR:
387✔
315
    fmt::format_to( std::back_inserter( w ), "local #{} :=", tkn.offset );
387✔
316
    break;
387✔
317
  case INS_ASSIGN_GLOBALVAR:
672✔
318
    fmt::format_to( std::back_inserter( w ), "global #{} :=", tkn.offset );
672✔
319
    break;
672✔
320

321
  case INS_GET_MEMBER:
372✔
322
    fmt::format_to( std::back_inserter( w ), "get-member {} (offset {})", string_at( tkn.offset ),
744✔
323
                    tkn.offset );
372✔
324
    break;
372✔
325
  case INS_SET_MEMBER:
3✔
326
    fmt::format_to( std::back_inserter( w ), "set-member {} (offset {})", string_at( tkn.offset ),
6✔
327
                    tkn.offset );
3✔
328
    break;
3✔
329
  case INS_SET_MEMBER_CONSUME:
147✔
330
    fmt::format_to( std::back_inserter( w ), "set-member-consume {} (offset {})",
147✔
331
                    string_at( tkn.offset ), tkn.offset );
294✔
332
    break;
147✔
333

334
  case INS_ADDMEMBER2:
45✔
335
    fmt::format_to( std::back_inserter( w ), "add uninitialized member ({}) to struct",
45✔
336
                    string_at( tkn.offset ) );
90✔
337
    break;
45✔
338
  case INS_ADDMEMBER_ASSIGN:
447✔
339
    fmt::format_to( std::back_inserter( w ), "add member ({}) to struct", string_at( tkn.offset ) );
894✔
340
    break;
447✔
341
  case INS_UNINIT:
96✔
342
    w += "push-uninit";
96✔
343
    break;
96✔
344
  case INS_DICTIONARY_ADDMEMBER:
126✔
345
    w += "add member to dictionary";
126✔
346
    break;
126✔
347

348
  case INS_GET_MEMBER_ID:
162✔
UNCOV
349
    fmt::format_to( std::back_inserter( w ), "get-member-id '{}' ({})",
×
350
                    getObjMember( tkn.offset )->code, tkn.offset );
162✔
351
    break;
162✔
352
  case INS_SET_MEMBER_ID:
3✔
UNCOV
353
    fmt::format_to( std::back_inserter( w ), "set-member-id '{}' ({})",
×
354
                    getObjMember( tkn.offset )->code, tkn.offset );
3✔
355
    break;
3✔
356
  case INS_SET_MEMBER_ID_CONSUME:
81✔
UNCOV
357
    fmt::format_to( std::back_inserter( w ), "set-member-id-consume '{}' ({})",
×
358
                    getObjMember( tkn.offset )->code, tkn.offset );
81✔
359
    break;
81✔
360
  case INS_CALL_METHOD_ID:
1,884✔
UNCOV
361
    fmt::format_to( std::back_inserter( w ), "call-method-id '{}' (#{}, {} arguments)",
×
362
                    getObjMethod( tkn.offset )->code, tkn.offset, tkn.type );
1,884✔
363
    break;
1,884✔
364

365
  case INS_SET_MEMBER_ID_CONSUME_PLUSEQUAL:
15✔
UNCOV
366
    fmt::format_to( std::back_inserter( w ), "set member id '{}' ({}) += #",
×
367
                    getObjMember( tkn.offset )->code, tkn.offset );
15✔
368
    break;
15✔
369
  case INS_SET_MEMBER_ID_CONSUME_MINUSEQUAL:
6✔
UNCOV
370
    fmt::format_to( std::back_inserter( w ), "set member id '{}' ({}) -=#",
×
371
                    getObjMember( tkn.offset )->code, tkn.offset );
6✔
372
    break;
6✔
373
  case INS_SET_MEMBER_ID_CONSUME_TIMESEQUAL:
6✔
UNCOV
374
    fmt::format_to( std::back_inserter( w ), "set member id '{}' ({}) *= #",
×
375
                    getObjMember( tkn.offset )->code, tkn.offset );
6✔
376
    break;
6✔
377
  case INS_SET_MEMBER_ID_CONSUME_DIVIDEEQUAL:
6✔
UNCOV
378
    fmt::format_to( std::back_inserter( w ), "set member id '{}' ({}) /= #",
×
379
                    getObjMember( tkn.offset )->code, tkn.offset );
6✔
380
    break;
6✔
381
  case INS_SET_MEMBER_ID_CONSUME_MODULUSEQUAL:
6✔
UNCOV
382
    fmt::format_to( std::back_inserter( w ), "set member id '{}' ({}) %= #",
×
383
                    getObjMember( tkn.offset )->code, tkn.offset );
6✔
384
    break;
6✔
385

386
  case TOK_SPREAD:
669✔
387
  {
UNCOV
388
    fmt::format_to( std::back_inserter( w ), "{} (TOK_SPREAD)",
×
389
                    tkn.offset ? "spread-into" : "create-spread" );
669✔
390

391
    break;
669✔
392
  }
393

394
  case TOK_FUNCTOR:
471✔
395
  {
UNCOV
396
    fmt::format_to( std::back_inserter( w ),
×
397
                    "create-functor index={} instructions={} (TOK_FUNCTOR)",
398
                    static_cast<int>( tkn.type ), tkn.offset );
471✔
399
    break;
471✔
400
  }
401

402
  case TOK_FUNCREF:
666✔
403
  {
404
    fmt::format_to( std::back_inserter( w ), "create-funcref index={} (TOK_FUNCREF)", tkn.offset );
666✔
405
    break;
666✔
406
  }
407

408
  case TOK_UNPLUSPLUS:
84✔
409
    w += "prefix unary ++";
84✔
410
    break;
84✔
411
  case TOK_UNMINUSMINUS:
48✔
412
    w += "prefix unary --";
48✔
413
    break;
48✔
414
  case TOK_UNPLUSPLUS_POST:
96✔
415
    w += "postfix unary ++";
96✔
416
    break;
96✔
417
  case TOK_UNMINUSMINUS_POST:
48✔
418
    w += "postfix unary --";
48✔
419
    break;
48✔
420
  case INS_SET_MEMBER_ID_UNPLUSPLUS:
9✔
UNCOV
421
    fmt::format_to( std::back_inserter( w ), "set member id '{}' unary ++",
×
422
                    getObjMember( tkn.offset )->code );
9✔
423
    break;
9✔
424
  case INS_SET_MEMBER_ID_UNMINUSMINUS:
12✔
UNCOV
425
    fmt::format_to( std::back_inserter( w ), "set member id '{}' unary --",
×
426
                    getObjMember( tkn.offset )->code );
12✔
427
    break;
12✔
428
  case INS_SET_MEMBER_ID_UNPLUSPLUS_POST:
3✔
UNCOV
429
    fmt::format_to( std::back_inserter( w ), "set member id '{}' unary ++ post",
×
430
                    getObjMember( tkn.offset )->code );
3✔
431
    break;
3✔
432
  case INS_SET_MEMBER_ID_UNMINUSMINUS_POST:
3✔
UNCOV
433
    fmt::format_to( std::back_inserter( w ), "set member id '{}' unary -- post",
×
434
                    getObjMember( tkn.offset )->code );
3✔
435
    break;
3✔
436
  case INS_SKIPIFTRUE_ELSE_CONSUME:
177✔
UNCOV
437
    fmt::format_to( std::back_inserter( w ),
×
438
                    "peek at top of stack; skip {}"
439
                    " instructions if true, otherwise consume it",
440
                    tkn.offset );
177✔
441
    break;
177✔
442
  case TOK_INTERPOLATE_STRING:
858✔
443
    fmt::format_to( std::back_inserter( w ), "interpolate string ({} parts)", tkn.offset );
858✔
444
    break;
858✔
445
  case TOK_FORMAT_EXPRESSION:
6✔
446
    w += "format expression";
6✔
447
    break;
6✔
448

449
  case INS_UNPACK_SEQUENCE:
99✔
450
  {
451
    int rest_index = tkn.offset > 0x7F ? ( ( tkn.offset >> 7 ) & 0x7F ) : -1;
99✔
UNCOV
452
    fmt::format_to( std::back_inserter( w ), "unpack sequence ({} elements, rest index {})",
×
453
                    tkn.offset & 0x7F, rest_index );
99✔
454
    break;
99✔
455
  }
456

457
  case INS_UNPACK_INDICES:
75✔
458
  {
459
    int rest_index = tkn.offset > 0x7F ? ( ( tkn.offset >> 7 ) & 0x7F ) : -1;
75✔
UNCOV
460
    fmt::format_to( std::back_inserter( w ), "unpack indices ({} elements, rest index {})",
×
461
                    tkn.offset & 0x7F, rest_index );
75✔
462
    break;
75✔
463
  }
464

465
  case INS_LOGICAL_JUMP:
38✔
UNCOV
466
    fmt::format_to( std::back_inserter( w ), "logical jump if {} to {}",
×
467
                    tkn.type != TYP_LOGICAL_JUMP_FALSE, tkn.offset );
38✔
468
    break;
38✔
469
  case INS_LOGICAL_CONVERT:
38✔
470
    w += "logical convert";
38✔
471
    break;
38✔
472

473
  default:
21✔
UNCOV
474
    fmt::format_to( std::back_inserter( w ), "id={:#x} type={} offset={} module={}", tkn.id,
×
475
                    tkn.type, tkn.offset, tkn.module );
42✔
476
  }
477
}
104,558✔
478

479
double StoredTokenDecoder::double_at( unsigned offset ) const
384✔
480
{
481
  if ( offset > data.size() - sizeof( double ) )
384✔
482
    throw std::runtime_error( "data overflow reading double at offset " + std::to_string( offset ) +
×
483
                              ".  Data size is " + std::to_string( data.size() ) );
×
484

485
  return *reinterpret_cast<const double*>( &data[offset] );
384✔
486
}
487

488
int StoredTokenDecoder::integer_at( unsigned offset ) const
8,570✔
489
{
490
  if ( offset > data.size() - sizeof( int ) )
8,570✔
491
    throw std::runtime_error( "data overflow reading integer at offset " +
×
492
                              std::to_string( offset ) + ".  Data size is " +
×
493
                              std::to_string( data.size() ) );
×
494

495
  return *reinterpret_cast<const int*>( &data[offset] );
8,570✔
496
}
497

498
uint16_t StoredTokenDecoder::uint16_t_at( unsigned offset ) const
330✔
499
{
500
  if ( offset > data.size() - sizeof( uint16_t ) )
330✔
501
    throw std::runtime_error( "data overflow reading uint16_t at offset " +
×
502
                              std::to_string( offset ) + ".  Data size is " +
×
503
                              std::to_string( data.size() ) );
×
504

505
  return *reinterpret_cast<const uint16_t*>( &data[offset] );
330✔
506
}
507

508
std::string StoredTokenDecoder::string_at( unsigned offset ) const
21,969✔
509
{
510
  if ( offset > data.size() )
21,969✔
511
    throw std::runtime_error( "data overflow reading string starting at offset " +
×
512
                              std::to_string( offset ) + ".  Data size is " +
×
513
                              std::to_string( data.size() ) );
×
514

515
  const char* s_begin = reinterpret_cast<const char*>( data.data() + offset );
21,969✔
516
  const char* data_end = reinterpret_cast<const char*>( data.data() + data.size() );
21,969✔
517

518
  auto s_end = std::find( s_begin, data_end, '\0' );
21,969✔
519
  if ( s_end == data_end )
21,969✔
520
    throw std::runtime_error( "No null terminator for string at offset " +
×
521
                              std::to_string( offset ) );
×
522

523
  return std::string( s_begin, s_end );
21,969✔
524
}
525

526
const Pol::Bscript::DebugToken& StoredTokenDecoder::debug_token_at( unsigned offset ) const
×
527
{
528
  if ( offset > data.size() - sizeof( Pol::Bscript::DebugToken ) )
×
529
    throw std::runtime_error( "data overflow reading DebugToken at offset " +
×
530
                              std::to_string( offset ) + ".  Data size is " +
×
531
                              std::to_string( data.size() ) );
×
532

533
  return *reinterpret_cast<const Pol::Bscript::DebugToken*>( &data[offset] );
×
534
}
535

536
void StoredTokenDecoder::decode_casejmp_table( std::string& w, unsigned offset ) const
87✔
537
{
538
  std::string indent( 24, ' ' );
87✔
539
  for ( ;; )
540
  {
541
    unsigned short jump_address = uint16_t_at( offset );
330✔
542
    offset += 2;
330✔
543
    auto type = static_cast<ESCRIPT_CASE_TYPES>( data.at( offset ) );
330✔
544
    offset++;
330✔
545

546
    if ( type == CASE_TYPE_LONG )
330✔
547
    {
548
      int value = integer_at( offset );
135✔
549
      offset += 4;
135✔
550
      fmt::format_to( std::back_inserter( w ), "\n{}{}: @{}", indent, value, jump_address );
270✔
551
    }
552
    else if ( type == CASE_TYPE_BOOL )
195✔
553
    {
554
      bool value = static_cast<bool>( data.at( offset ) );
18✔
555
      offset += 1;
18✔
556
      fmt::format_to( std::back_inserter( w ), "\n{}{}: @{}", indent, value, jump_address );
36✔
557
    }
558
    else if ( type == CASE_TYPE_UNINIT )
177✔
559
    {
560
      fmt::format_to( std::back_inserter( w ), "\n{}<uninit>: @{}", indent, jump_address );
12✔
561
    }
562
    else if ( type == CASE_TYPE_DEFAULT )
171✔
563
    {
564
      fmt::format_to( std::back_inserter( w ), "\n{}default: @{}", indent, jump_address );
87✔
565
      break;
87✔
566
    }
567
    else if ( type == CASE_TYPE_STRING )
84✔
568
    {
569
      unsigned string_length = static_cast<unsigned>( data.at( offset ) );
84✔
570
      offset += 1;
84✔
571
      if ( offset + string_length > data.size() )
84✔
572
        throw std::runtime_error( "casejmp string at offset " + std::to_string( offset ) + " of " +
×
573
                                  std::to_string( string_length ) +
×
574
                                  " characters exceeds data size of " +
×
575
                                  std::to_string( data.size() ) );
×
576

577
      const char* s_begin = reinterpret_cast<const char*>( data.data() + offset );
84✔
578
      std::string contents( s_begin, s_begin + string_length );
84✔
579
      fmt::format_to( std::back_inserter( w ), "\n{}{}: @{}", indent,
84✔
580
                      Clib::getencodedquotedstring( contents ), jump_address );
168✔
581
      offset += string_length;
84✔
582
    }
84✔
583
    else
584
    {
585
      throw std::runtime_error( "casejmp unhandled type " + std::to_string( type ) );
×
586
    }
587
  }
243✔
588
}
87✔
589

590
}  // namespace Pol::Bscript::Compiler
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