Skip to content

Fix description of pointer in ldloca.s #11314

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Smaug123
Copy link
Contributor

Summary

ECMA-335 6th edition states:

The ldloca instruction pushes the address of the local variable number indx onto the stack, where local variables are numbered 0 onwards. The value pushed on the stack is already aligned correctly for use with instructions like ldind and stind. The result is a managed pointer (type &).

The docs for ldloca already state that the result is a managed pointer; this PR brings the docs for ldloca.s into alignment with the spec and the docs for ldloca. (I hope that this change is in fact correct!)

@Smaug123 Smaug123 requested a review from a team as a code owner May 18, 2025 22:24
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label May 18, 2025
@@ -10423,7 +10423,7 @@ The following <xref:System.Reflection.Emit.ILGenerator.Emit%2A> method overloads

1. The address stored in the local variable at the specified index is pushed onto the stack.

The `ldloca.s` instruction pushes the address of the local variable number at the passed index onto the stack, where local variables are numbered 0 onwards. The value pushed on the stack is already aligned correctly for use with instructions like <xref:System.Reflection.Emit.OpCodes.Ldind_I> and <xref:System.Reflection.Emit.OpCodes.Stind_I>. The result is a transient pointer (type `*`).
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 concerned that I don't have a plausible story for how this kind of mistake could have been made, so I'm not enormously confident that this is a mistake. But on main the docs are not internally consistent between ldloca and ldloca.s.

The spec appears to be ambiguous. It contains two usages of the term "transient pointer":

Instructions that create pointers which are guaranteed not to point into the memory manager’s heaps (e.g., ldloca, ldarga, and ldsflda) produce transient pointers (type *) that can be used wherever a managed pointer (type &) or unmanaged pointer (type native unsigned int) is expected.

and

*, a “transient pointer,” which can be used only within the body of a single method, that points to a value known to be in unmanaged memory (see the CIL Instruction Set specification for more details. * types are generated internally within the CLI; they are not created by the user).

But then the spec for ldloca is explicit:

The result is a managed pointer (type &).

So really I don't know what the correct resolution is, or even what the semantics are.

@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 20, 2025
@gewarren gewarren added area-System.Reflection.Emit and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Reflection.Emit community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants