Skip to content

Use classes + virtual functions for BinaryReader#376

Merged
binji merged 1 commit intomasterfrom
binary-reader
Mar 30, 2017
Merged

Use classes + virtual functions for BinaryReader#376
binji merged 1 commit intomasterfrom
binary-reader

Conversation

@binji
Copy link
Member

@binji binji commented Mar 29, 2017

This adds a few new classes:

  • BinaryReader: the abstract base class
  • BinaryReaderNop: implements all of BinaryReader, but does nothing
  • LoggingBinaryReader: logs calls through BinaryReader, and forwards to
    another BinaryReader

Typically this means we can remove the Context structs from these
implementations, since that data can just move into the BinaryReader
subclasses.

I also took the opportunity to rename the new member functions to
MixedCase instead of snake_case, since that's more common in C++.

@binji binji requested review from KarlSchimpf and sbc100 March 29, 2017 23:01
@pipcet
Copy link
Contributor

pipcet commented Mar 30, 2017

Would it make sense to make state a member of the BinaryReader class rather than passing it by reference to all callbacks? Not a hundred percent clean to have a data member in the abstract base class, but it would save a lot of code...

@binji
Copy link
Member Author

binji commented Mar 30, 2017

@pipcet I had it that way at first, but it makes the forwarding in LoggingBinaryReader clunky, since you have to copy the values in before every callback. This seemed less error-prone, and would expand to other things too (like having a ChainBinaryReader or whatever). What do you think?

@pipcet
Copy link
Contributor

pipcet commented Mar 30, 2017

@binji I see. I must say I'd still prefer not to have that state argument, which appears to be unused 90% of the time. It's like having two void * arguments in a C callback...

I must confess I can't think of a perfectly clean way of doing this, my best attempt is:

When parsing starts, the BinaryReader's BeginModule method is called with a BinaryReader::State* state argument. The base class simply stores that argument and provides a getInputOffset() method to access the offset (that appears to be the only part that is actually used?).

That would be the least code, I think (LoggingReader can pass through the state pointer rather than having to copy data) and shouldn't reduce performance, while still allowing the state class to grow to include more state.

It's a bit C-like in using actual pointers though, so I fully understand if you prefer leaving things as in the PR; either way, I think, this PR is a huge improvement.

@binji
Copy link
Member Author

binji commented Mar 30, 2017

Yeah, that's not bad. I'll try it out and see.

@binji
Copy link
Member Author

binji commented Mar 30, 2017

Thanks for the suggestion, @pipcet. This is much nicer.

Copy link
Member

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

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

Mostly looks awesome! Great to see so many casts removed

context->section_starts[static_cast<size_t>(section_code)] = ctx->offset;
Result BinaryReaderObjdumpPrepass::OnFunctionName(uint32_t index,
StringSlice name) {
if (options->mode == ObjdumpMode::Prepass) {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this condition needed? Shouldn't it just be split into two different methods? On a related note is seems strange for BinaryReaderObjdump to inherit from BinaryReaderObjdumpPrepass. Could they both inherit from some common base class instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

PrintDetails(" - %-18s idx=%#-4x addend=%#-4x offset=%#x(file=%#x)\n",
get_reloc_type_name(type), index, addend, offset, total_offset);
if (options->mode == ObjdumpMode::Prepass &&
reloc_section == BinarySection::Code) {
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

/* MEMORY section data */
Limits memory_limits;
};
} data;
Copy link
Member

Choose a reason for hiding this comment

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

Is this change related?

Copy link
Member Author

Choose a reason for hiding this comment

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

Kinda. I started getting a bug because this union wasn't initialized to zero. It seemed easiest to name it so I could do WABT_ZERO_MEMORY(data)

OnReturnExpr
EndFunctionBody(0)
EndCodeSection
EndModule
Copy link
Member

Choose a reason for hiding this comment

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

Looks like the looking used to happen twice here? Was that am existing bug?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh weird, I didn't even notice. Yeah, must have been an existing bug.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I forgot. the BinaryReaderInterpreter did two passes over the binary before since you need to first validate all the modifications to the data and elem segments, then only apply them if all are valid. This turned out to be a pain for the new system, so I ended up using two vectors to store the modifications and updating them later.

This adds a few new classes:

* BinaryReader: the abstract base class
* BinaryReaderNop: implements all of BinaryReader, but does nothing
* BinaryReaderLogging: logs calls through BinaryReader, and forwards to
  another BinaryReader

Typically this means we can remove the Context structs from these
implementations, since that data can just move into the BinaryReader
subclasses.

I also took the opportunity to rename the new member functions to
MixedCase instead of snake_case, since that's more common in C++.
@binji binji merged commit ca9cccc into master Mar 30, 2017
@binji binji deleted the binary-reader branch March 30, 2017 21:17
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