-
Notifications
You must be signed in to change notification settings - Fork 836
[NFC] Refactor code to reduce boilerplate for new code annotations #8246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5daee4c
7ce3151
477e77b
83583cb
073b39e
f129e51
075fd15
d540a96
4d8b7a5
e38e29c
c78dc41
8ad0110
d876266
31f6e5c
879dc79
eadd3dc
a49fe26
c2c1d9d
dce83d8
93234e2
eeba297
902a233
2e287a2
45650e1
017f8e5
4097eec
694e4f9
a815fb7
0f3f313
937b873
1e499ab
a0e1183
2364fb8
0212940
be7922c
d83c913
35df904
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1297,39 +1297,63 @@ struct ParseImplicitTypeDefsCtx : TypeParserCtx<ParseImplicitTypeDefsCtx> { | |
| }; | ||
|
|
||
| struct AnnotationParserCtx { | ||
| // Return the inline hint for a call instruction, if there is one. | ||
| std::optional<std::uint8_t> | ||
| getInlineHint(const std::vector<Annotation>& annotations) { | ||
| // Find and apply (the last) inline hint. | ||
| const Annotation* hint = nullptr; | ||
| // Parse annotations into IR. | ||
| CodeAnnotation parseAnnotations(const std::vector<Annotation>& annotations) { | ||
| CodeAnnotation ret; | ||
|
|
||
| // Find the hints. For hints with content we must find the last one, which | ||
| // overrides the others. | ||
| const Annotation* branchHint = nullptr; | ||
| const Annotation* inlineHint = nullptr; | ||
| for (auto& a : annotations) { | ||
| if (a.kind == Annotations::InlineHint) { | ||
| hint = &a; | ||
| if (a.kind == Annotations::BranchHint) { | ||
| branchHint = &a; | ||
| } else if (a.kind == Annotations::InlineHint) { | ||
| inlineHint = &a; | ||
| } | ||
| } | ||
| if (!hint) { | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| Lexer lexer(hint->contents); | ||
| if (lexer.empty()) { | ||
| std::cerr << "warning: empty InlineHint\n"; | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| auto str = lexer.takeString(); | ||
| if (!str || str->size() != 1) { | ||
| std::cerr << "warning: invalid InlineHint string\n"; | ||
| return std::nullopt; | ||
| // Apply the last branch hint, if valid. | ||
| if (branchHint) { | ||
| Lexer lexer(branchHint->contents); | ||
| if (lexer.empty()) { | ||
| std::cerr << "warning: empty BranchHint\n"; | ||
| } else { | ||
| auto str = lexer.takeString(); | ||
| if (!str || str->size() != 1) { | ||
| std::cerr << "warning: invalid BranchHint string\n"; | ||
| } else { | ||
| auto value = (*str)[0]; | ||
| if (value != 0 && value != 1) { | ||
| std::cerr << "warning: invalid BranchHint value\n"; | ||
| } else { | ||
| ret.branchLikely = bool(value); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| uint8_t value = (*str)[0]; | ||
| if (value > 127) { | ||
| std::cerr << "warning: invalid InlineHint value\n"; | ||
| return std::nullopt; | ||
| // Apply the last inline hint, if valid. | ||
| if (inlineHint) { | ||
| Lexer lexer(inlineHint->contents); | ||
| if (lexer.empty()) { | ||
| std::cerr << "warning: empty InlineHint\n"; | ||
| } else { | ||
| auto str = lexer.takeString(); | ||
| if (!str || str->size() != 1) { | ||
| std::cerr << "warning: invalid InlineHint string\n"; | ||
| } else { | ||
| uint8_t value = (*str)[0]; | ||
| if (value > 127) { | ||
| std::cerr << "warning: invalid InlineHint value\n"; | ||
| } else { | ||
| ret.inline_ = value; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return value; | ||
| return ret; | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -2000,10 +2024,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx { | |
| if (!type.isSignature()) { | ||
| return in.err(pos, "expected function type"); | ||
| } | ||
| auto likely = getBranchHint(annotations); | ||
| return withLoc( | ||
| pos, | ||
| irBuilder.makeIf(label ? *label : Name{}, type.getSignature(), likely)); | ||
| return withLoc(pos, | ||
| irBuilder.makeIf(label ? *label : Name{}, | ||
| type.getSignature(), | ||
| parseAnnotations(annotations))); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we just pass a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly, good question... Looking around a little, that would change hundreds of lines in the parser, so seems like a large refactoring. Perhaps we can consider it after? |
||
| } | ||
|
|
||
| Result<> visitElse() { return withLoc(irBuilder.visitElse()); } | ||
|
|
@@ -2422,8 +2446,8 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx { | |
| const std::vector<Annotation>& annotations, | ||
| Name func, | ||
| bool isReturn) { | ||
| auto inline_ = getInlineHint(annotations); | ||
| return withLoc(pos, irBuilder.makeCall(func, isReturn, inline_)); | ||
| return withLoc( | ||
| pos, irBuilder.makeCall(func, isReturn, parseAnnotations(annotations))); | ||
| } | ||
|
|
||
| Result<> makeCallIndirect(Index pos, | ||
|
|
@@ -2433,52 +2457,18 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx { | |
| bool isReturn) { | ||
| auto t = getTable(pos, table); | ||
| CHECK_ERR(t); | ||
| auto inline_ = getInlineHint(annotations); | ||
| return withLoc(pos, | ||
| irBuilder.makeCallIndirect(*t, type, isReturn, inline_)); | ||
| } | ||
|
|
||
| // Return the branch hint for a branching instruction, if there is one. | ||
| std::optional<bool> | ||
| getBranchHint(const std::vector<Annotation>& annotations) { | ||
| // Find and apply (the last) branch hint. | ||
| const Annotation* hint = nullptr; | ||
| for (auto& a : annotations) { | ||
| if (a.kind == Annotations::BranchHint) { | ||
| hint = &a; | ||
| } | ||
| } | ||
| if (!hint) { | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| Lexer lexer(hint->contents); | ||
| if (lexer.empty()) { | ||
| std::cerr << "warning: empty BranchHint\n"; | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| auto str = lexer.takeString(); | ||
| if (!str || str->size() != 1) { | ||
| std::cerr << "warning: invalid BranchHint string\n"; | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| auto value = (*str)[0]; | ||
| if (value != 0 && value != 1) { | ||
| std::cerr << "warning: invalid BranchHint value\n"; | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| return bool(value); | ||
| irBuilder.makeCallIndirect( | ||
| *t, type, isReturn, parseAnnotations(annotations))); | ||
| } | ||
|
|
||
| Result<> makeBreak(Index pos, | ||
| const std::vector<Annotation>& annotations, | ||
| Index label, | ||
| bool isConditional) { | ||
| auto likely = getBranchHint(annotations); | ||
| return withLoc(pos, irBuilder.makeBreak(label, isConditional, likely)); | ||
| return withLoc( | ||
| pos, | ||
| irBuilder.makeBreak(label, isConditional, parseAnnotations(annotations))); | ||
| } | ||
|
|
||
| Result<> makeSwitch(Index pos, | ||
|
|
@@ -2617,8 +2607,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx { | |
| const std::vector<Annotation>& annotations, | ||
| HeapType type, | ||
| bool isReturn) { | ||
| auto inline_ = getInlineHint(annotations); | ||
| return withLoc(pos, irBuilder.makeCallRef(type, isReturn, inline_)); | ||
| return withLoc( | ||
| pos, | ||
| irBuilder.makeCallRef(type, isReturn, parseAnnotations(annotations))); | ||
| } | ||
|
|
||
| Result<> makeRefI31(Index pos, | ||
|
|
@@ -2658,8 +2649,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx { | |
| BrOnOp op, | ||
| Type in = Type::none, | ||
| Type out = Type::none) { | ||
| auto likely = getBranchHint(annotations); | ||
| return withLoc(pos, irBuilder.makeBrOn(label, op, in, out, likely)); | ||
| return withLoc( | ||
| pos, | ||
| irBuilder.makeBrOn(label, op, in, out, parseAnnotations(annotations))); | ||
| } | ||
|
|
||
| Result<> makeStructNew(Index pos, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really related to this change, but it looks like
parseAnnotationscould just be a free function instead of accessed via multiple inheritance fromAnnotationParserCtx.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable either way to me, I don't feel strongly.