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
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion xml/System.Reflection.Emit/OpCodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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 managed pointer (type `&`).

The `ldloca.s` instruction provides an efficient encoding for use with the local variables 0 through 255.

Expand Down