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

Reduce "unsafe" by replacing byte* pointer usage with ReadOnlySpan<byte> #3106

Merged
merged 2 commits into from
Nov 1, 2023

Conversation

fowl2
Copy link
Contributor

@fowl2 fowl2 commented Oct 18, 2023

This replaces all the unsafe code involved in metadata parsing in the ILSpy project with the equivalent using ReadOnlySpan<byte>. There's a little bit left in ICSharpCode.Decompiler, mostly around resource handling.

Not sure if it's worth it, especially given possible performance regression when running on netfx, but since I already did it as an experiment, it might be useful to the project.

side note: I think all ECMA 335 metadata is little endian, but the code doesn't really seem to deal with that. I don't think .net runs on any big endian machines anymore anyway.

@siegfriedpammer siegfriedpammer added this to the 8.2 milestone Oct 23, 2023
{
// endianess?
Copy link
Member

Choose a reason for hiding this comment

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

If I am not mistaken, the code below assumes little endian byte-order and ECMA335 states that big endian byte-order is only used in signatures. Maybe we should call this method "GetValueLittleEndian"?

Copy link
Member

Choose a reason for hiding this comment

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

When decoding signatures, we should not need this method, as we already have access to the raw bytes and SRM BlobReader already exposes helpers that handle compressed integers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. renamed GetValueLittleEndian
  2. unless I'm misunderstanding these are not "compressed", they are just either "small" (2 byte) or "large" (4 bytes) depending on the size of the table they're indexing. Maybe this could be a ReadTableIndex or something, but I'm not sure how that would work.

Copy link
Member

Choose a reason for hiding this comment

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

I don't follow...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm sorry, what is unclear? Which method on BlobReader could we use instead of GetValueLittleEndian?

Copy link
Member

Choose a reason for hiding this comment

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

OK... now I understand... sorry.... apparently my second comment yesterday was the confusing one: It was just meant as additional information regarding LE vs BE encoding used in ECMA335. BE is only used in signature blobs, in which case we don't need GetValue (now called "GetValueLittleEndian"), because SRMs BlobReader already supports all the different primitive types used in signatures.

I did not mean to suggest using BlobReader instead of GetValue/GetValueLittleEndian. However, now that I think more about it, maybe we could/should use the methods found in BinaryPrimitives instead? Not sure whether that's a good idea for all the different uses of the method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean reimplementing GetValueLittleEndian in terms of BinaryPrimitives, or in each of the callers?

Also, it is public - do we have to go though a obsoletion/deprecation process or can it just be changed/removedv?

Copy link
Member

Choose a reason for hiding this comment

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

I don't expect anyone to actually use the method outside of the decompiler engine or ILSpy, however, wouldn't do any harm to deprecate the original overload (the one that uses pointers) and keep the name "GetValue" so we don't break anyone, right?

I think all the uses of GetValue(LittleEndian) could be directly replaced by BinaryPrimitives?

@siegfriedpammer siegfriedpammer merged commit 0bab8a0 into icsharpcode:master Nov 1, 2023
5 checks passed
@siegfriedpammer
Copy link
Member

Thank you for your contribution!

@fowl2 fowl2 deleted the unsafeToSpan branch November 2, 2023 01:28
mattsh247 pushed a commit to mattsh247/ILSpy that referenced this pull request Jul 30, 2024
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.

2 participants