@@ -101,6 +101,11 @@ class S2WasmBuilder {
101
101
abort (); \
102
102
}
103
103
104
+ bool peek (const char *pattern) {
105
+ size_t size = strlen (pattern);
106
+ return strncmp (s, pattern, size) == 0 ;
107
+ }
108
+
104
109
// match and skip the pattern, if matched
105
110
bool match (const char *pattern) {
106
111
size_t size = strlen (pattern);
@@ -396,17 +401,19 @@ class S2WasmBuilder {
396
401
else if (match (" ident" )) {}
397
402
else if (match (" section" )) parseToplevelSection ();
398
403
else if (match (" align" ) || match (" p2align" )) s = strchr (s, ' \n ' );
399
- else if (match (" Lfunc_end" )) {
400
- // skip the next line, which has a .size we can ignore
401
- s = strstr (s, " .size" );
402
- s = strchr (s, ' \n ' );
403
- } else if (match (" globl" )) parseGlobl ();
404
+ else if (match (" globl" )) parseGlobl ();
404
405
else abort_on (" process" );
405
406
}
406
407
}
407
408
408
409
void parseToplevelSection () {
409
410
auto section = getCommaSeparated ();
411
+ // Skipping .debug_ sections
412
+ if (!strncmp (section.c_str (), " .debug_" , strlen (" .debug_" ))) {
413
+ const char *next = strstr (s, " .section" );
414
+ s = !next ? s + strlen (s) : next;
415
+ return ;
416
+ }
410
417
// Initializers are anything in a section whose name begins with .init_array
411
418
if (!strncmp (section.c_str (), " .init_array" , strlen (" .init_array" ) - 1 )) {
412
419
parseInitializer ();
@@ -449,15 +456,24 @@ class S2WasmBuilder {
449
456
}
450
457
451
458
void parseFile () {
452
- assert (*s == ' "' );
459
+ if (*s != ' "' ) {
460
+ // TODO: optimize, see recordFile below
461
+ size_t fileId = getInt ();
462
+ skipWhitespace ();
463
+ std::vector<char > quoted = getQuoted ();
464
+ WASM_UNUSED (fileId); WASM_UNUSED (quoted); // TODO: use the fileId and quoted
465
+ s = strchr (s, ' \n ' );
466
+ return ;
467
+ }
468
+ // '.file' without first index argument points to bc-file
453
469
s++;
454
470
std::string filename;
455
471
while (*s != ' "' ) {
456
472
filename += *s;
457
473
s++;
458
474
}
459
475
s++;
460
- // TODO: use the filename?
476
+ WASM_UNUSED (filename); // TODO: use the filename
461
477
}
462
478
463
479
void parseGlobl () {
@@ -485,11 +501,31 @@ class S2WasmBuilder {
485
501
486
502
mustMatch (" :" );
487
503
488
- if (match (" .Lfunc_begin" )) {
504
+ auto recordFile = [&]() {
505
+ if (debug) dump (" file" );
506
+ size_t fileId = getInt ();
507
+ skipWhitespace ();
508
+ std::vector<char > quoted = getQuoted ();
509
+ WASM_UNUSED (fileId); WASM_UNUSED (quoted); // TODO: use the fileId and quoted
489
510
s = strchr (s, ' \n ' );
490
- s++;
511
+ };
512
+ auto recordLoc = [&]() {
513
+ if (debug) dump (" loc" );
514
+ size_t fileId = getInt ();
491
515
skipWhitespace ();
492
- }
516
+ size_t row = getInt ();
517
+ skipWhitespace ();
518
+ size_t column = getInt ();
519
+ WASM_UNUSED (fileId); WASM_UNUSED (row); WASM_UNUSED (column); // TODO: use the fileId, row and column
520
+ s = strchr (s, ' \n ' );
521
+ };
522
+ auto recordLabel = [&]() {
523
+ if (debug) dump (" label" );
524
+ Name label = getStrToSep ();
525
+ // TODO: track and create map of labels and their ranges for our AST
526
+ WASM_UNUSED (label);
527
+ s = strchr (s, ' \n ' );
528
+ };
493
529
494
530
unsigned nextId = 0 ;
495
531
auto getNextId = [&nextId]() {
@@ -523,6 +559,15 @@ class S2WasmBuilder {
523
559
skipWhitespace ();
524
560
if (!match (" ," )) break ;
525
561
}
562
+ } else if (match (" .file" )) {
563
+ recordFile ();
564
+ skipWhitespace ();
565
+ } else if (match (" .loc" )) {
566
+ recordLoc ();
567
+ skipWhitespace ();
568
+ } else if (peek (" .Lfunc_begin" )) {
569
+ recordLabel ();
570
+ skipWhitespace ();
526
571
} else break ;
527
572
}
528
573
Function* func = builder.makeFunction (name, std::move (params), resultType, std::move (vars));
@@ -644,6 +689,7 @@ class S2WasmBuilder {
644
689
auto curr = allocator->alloc <Unary>();
645
690
curr->op = op;
646
691
curr->value = getInput ();
692
+ curr->type = type;
647
693
curr->finalize ();
648
694
setOutput (curr, assign);
649
695
};
@@ -935,8 +981,13 @@ class S2WasmBuilder {
935
981
} else if (match (" end_block" )) {
936
982
bstack.back ()->cast <Block>()->finalize ();
937
983
bstack.pop_back ();
938
- } else if (match (" .LBB" )) {
939
- s = strchr (s, ' \n ' );
984
+ } else if (peek (" .LBB" )) {
985
+ // FIXME legacy tests: it can be leftover from "loop" or "block", but it can be a label too
986
+ auto p = s;
987
+ while (*p && *p != ' :' && *p != ' #' && *p != ' \n ' ) p++;
988
+ if (*p == ' :' ) { // it's a label
989
+ recordLabel ();
990
+ } else s = strchr (s, ' \n ' );
940
991
} else if (match (" loop" )) {
941
992
auto curr = allocator->alloc <Loop>();
942
993
addToBlock (curr);
@@ -997,8 +1048,30 @@ class S2WasmBuilder {
997
1048
makeHost (CurrentMemory);
998
1049
} else if (match (" grow_memory" )) {
999
1050
makeHost1 (GrowMemory);
1051
+ } else if (peek (" .Lfunc_end" )) {
1052
+ // TODO fix handwritten tests to have .endfunc
1053
+ recordLabel ();
1054
+ // skip the next line, which has a .size we can ignore
1055
+ s = strstr (s, " .size" );
1056
+ s = strchr (s, ' \n ' );
1057
+ break ; // the function is done
1000
1058
} else if (match (" .endfunc" )) {
1059
+ skipWhitespace ();
1060
+ // getting all labels at the end of function
1061
+ while (peek (" .L" ) && strchr (s, ' :' ) < strchr (s, ' \n ' )) {
1062
+ recordLabel ();
1063
+ skipWhitespace ();
1064
+ }
1065
+ // skip the next line, which has a .size we can ignore
1066
+ s = strstr (s, " .size" );
1067
+ s = strchr (s, ' \n ' );
1001
1068
break ; // the function is done
1069
+ } else if (match (" .file" )) {
1070
+ recordFile ();
1071
+ } else if (match (" .loc" )) {
1072
+ recordLoc ();
1073
+ } else if (peek (" .L" ) && strchr (s, ' :' ) < strchr (s, ' \n ' )) {
1074
+ recordLabel ();
1002
1075
} else {
1003
1076
abort_on (" function element" );
1004
1077
}
0 commit comments