Skip to content
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

Adds binary read support for delimited arg groups #870

Merged
merged 2 commits into from
Dec 5, 2024

Conversation

zslayton
Copy link
Contributor

@zslayton zslayton commented Dec 4, 2024

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor Author

@zslayton zslayton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ PR tour 🧭

Comment on lines -337 to -352
let bytes_to_read = match group_header_flex_uint.value() {
0 => todo!("delimited argument groups"),
n_bytes => n_bytes as usize,
};
// If it's length-prefixed, we don't need to inspect its contents. We can build an
// ArgGroup using the unexamined bytes; we'll parse them later if they get evaluated.
let arg_group_length = group_header_flex_uint.size_in_bytes() + bytes_to_read;
let arg_group = BinaryEExpArgGroup::new(
parameter,
self.remaining_args_buffer.slice(0, arg_group_length),
group_header_flex_uint.size_in_bytes() as u8,
);
(
EExpArg::new(parameter, EExpArgExpr::ArgGroup(arg_group)),
self.remaining_args_buffer.consume(arg_group_length),
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ This segment was moved into the match arm on line 367, starting with n_bytes =>.

match group_header_flex_uint.value() {
// A FlexUInt of `0` indicates that the arg group is delimited.
// We need to step through it to determine its span.
0 if *parameter.encoding() == ParameterEncoding::Tagged => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ This arm contains the new logic.

Comment on lines +367 to +379
n_bytes => {
let bytes_to_read = n_bytes as usize;
let arg_group_length =
group_header_flex_uint.size_in_bytes() + bytes_to_read;
let arg_group = BinaryEExpArgGroup::new(
parameter,
self.remaining_args_buffer.slice(0, arg_group_length),
group_header_flex_uint.size_in_bytes() as u8,
);
(
EExpArg::new(parameter, EExpArgExpr::ArgGroup(arg_group)),
self.remaining_args_buffer.consume(arg_group_length),
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ Relocated here from above.

@zslayton zslayton marked this pull request as ready for review December 4, 2024 20:01
Copy link

codecov bot commented Dec 4, 2024

Codecov Report

Attention: Patch coverage is 94.94949% with 5 lines in your changes missing coverage. Please review.

Project coverage is 77.91%. Comparing base (ed541e8) to head (e1b477b).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/lazy/binary/raw/v1_1/e_expression.rs 93.84% 2 Missing and 2 partials ⚠️
src/lazy/expanded/macro_evaluator.rs 96.42% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #870      +/-   ##
==========================================
+ Coverage   77.87%   77.91%   +0.03%     
==========================================
  Files         136      136              
  Lines       34314    34385      +71     
  Branches    34314    34385      +71     
==========================================
+ Hits        26723    26791      +68     
- Misses       5630     5631       +1     
- Partials     1961     1963       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@popematt popematt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one part where I am a bit confused, and it would help to have some more explanation, but otherwise it looks good. I've commented on a few other minor things that are not blockers.

/// The iterator is parsing expressions from a slice of the input buffer
Input(BinaryBuffer<'top>),
/// The iterator is iterating over the bump-allocated cache of previously parsed expressions.
Cache(&'top [LazyRawValueExpr<'top, BinaryEncoding_1_1>]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the name and doc comments suggest to me that these expressions could be shared somehow. (Maybe there's a variable that's used more than once...?) Yet, further down, I see that this is being mutated. Is this actually a slice that points to a cache that is owned somewhere else? And it's effectively just the start and length of the slice that is updated?

Are any of those cached expressions stateful? Are we sure that there's no possibility of interference between different use-sites of the same cached expressions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of BinaryEExpArgGroupIteratorSource's variants refer to data stored elsewhere with a lifetime of 'top:

  • In the Input case, the BinaryBuffer holds a slice of the input buffer, which is frozen for the duration of 'top.
  • In the Cache case, the reader bump-allocated a &'top [...] in which to store raw lexed expressions it found as it traversed a delimited group. Data stored in the bump is guaranteed to outlive 'top.

BinaryEExpArgGroupIteratorSource instances are immutable, but they are each wrapped by a BinaryEExpArgGroupIterator that is mutable. Each time the iterator's next() method is called, it either advances the slice of the source's Input variant that it holds or it pops the head off of the slice of the Cache variant that it holds.

Both the iterator and its source are trivially copy-able, so you could easily/safely make several iterators traversing the expression group at once. Each iterator would mutate its own state as it traversed the immutable source data.

Is that helpful?

src/lazy/binary/raw/v1_1/value.rs Outdated Show resolved Hide resolved
src/lazy/expanded/macro_evaluator.rs Outdated Show resolved Hide resolved
src/lazy/expanded/macro_evaluator.rs Outdated Show resolved Hide resolved
@zslayton zslayton merged commit 804ee88 into main Dec 5, 2024
35 checks passed
@zslayton zslayton deleted the delimited-arg-group branch December 5, 2024 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants