Skip to content

Commit 5aa2e18

Browse files
authored
[Parser] Start to parse instructions (#4789)
Update gen-s-parser.py to produce a second version of its parsing code that works with the new wat parser. The new version automatically replaces the `s` element argument in the existing parser with the `ctx` and `in` arguments used by the new parser, so adding new instructions will not require any additional work in gen-s-parser.py after this change. Also add stub `make***` functions to the new wat parser, with a few filled out, namely `makeNop`, `makeUnreachable`, `makeConst`, and `makeRefNull`. Update the `global` parser to parse global initializer instructions and update wat-kitchen-sink.wast to demonstrate that the instructions are parsed correctly. Adding new instruction classes will require adding a new `make***` function to wat-parser.cpp in additional to wasm-s-parser.{h,cpp} after this change, but adding a trivial failing implementation is good enough for the time being, so I don't expect this to appreciably increase our maintenance burden in the near term. The infrastructure for parsing folded instructions, instructions with operands, and control flow instructions will be implemented in future PRs.
1 parent e2ce69c commit 5aa2e18

File tree

4 files changed

+6796
-93
lines changed

4 files changed

+6796
-93
lines changed

scripts/gen-s-parser.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ def insert(self, inst, expr):
693693
self.do_insert(inst, inst, expr)
694694

695695

696-
def instruction_parser():
696+
def instruction_parser(new_parser=False):
697697
"""Build a trie out of all the instructions, then emit it as C++ code."""
698698
trie = Node()
699699
inst_length = 0
@@ -703,12 +703,23 @@ def instruction_parser():
703703

704704
printer = CodePrinter()
705705

706-
printer.print_line("char op[{}] = {{'\\0'}};".format(inst_length + 1))
707-
printer.print_line("strncpy(op, s[0]->c_str(), {});".format(inst_length))
706+
if not new_parser:
707+
printer.print_line("char op[{}] = {{'\\0'}};".format(inst_length + 1))
708+
printer.print_line("strncpy(op, s[0]->c_str(), {});".format(inst_length))
708709

709710
def print_leaf(expr, inst):
710-
printer.print_line("if (strcmp(op, \"{inst}\") == 0) {{ return {expr}; }}"
711-
.format(inst=inst, expr=expr))
711+
if new_parser:
712+
expr = expr.replace("()", "(ctx)")
713+
expr = expr.replace("(s", "(ctx, in")
714+
printer.print_line("if (op == \"{inst}\"sv) {{".format(inst=inst))
715+
with printer.indent():
716+
printer.print_line("auto ret = {expr};".format(expr=expr))
717+
printer.print_line("CHECK_ERR(ret);")
718+
printer.print_line("return *ret;")
719+
printer.print_line("}")
720+
else:
721+
printer.print_line("if (strcmp(op, \"{inst}\") == 0) {{ return {expr}; }}"
722+
.format(inst=inst, expr=expr))
712723
printer.print_line("goto parse_error;")
713724

714725
def emit(node, idx=0):
@@ -737,7 +748,10 @@ def emit(node, idx=0):
737748
emit(trie)
738749
printer.print_line("parse_error:")
739750
with printer.indent():
740-
printer.print_line("throw ParseException(std::string(op), s.line, s.col);")
751+
if new_parser:
752+
printer.print_line("return in.err(\"unrecognized instruction\");")
753+
else:
754+
printer.print_line("throw ParseException(std::string(op), s.line, s.col);")
741755

742756

743757
def print_header():
@@ -763,6 +777,8 @@ def main():
763777
sys.exit(1)
764778
print_header()
765779
generate_with_guard(instruction_parser, "INSTRUCTION_PARSER")
780+
print()
781+
generate_with_guard(lambda: instruction_parser(True), "NEW_INSTRUCTION_PARSER")
766782
print_footer()
767783

768784

0 commit comments

Comments
 (0)