-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Open
Labels
JitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triagearea-Codegen-meta-mononeeds-further-triageIssue has been initially triaged, but needs deeper consideration or reconsiderationIssue has been initially triaged, but needs deeper consideration or reconsideration
Milestone
Description
Is there an existing issue for this?
- I have searched the existing issuesTo pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Describe the bug
Type layout below causes System.TypeInitializationException
to be thrown in WASM (same code can run in a server-type project):
public sealed class TwistedType {
public static IEnumerable<TwistedType> TheTroubleMaker = NestedStatic.ArrayOfTwistedType.Prepend(new());
public static class NestedStatic {
public static TwistedType[] ArrayOfTwistedType = { new() };
}
public string World { get; } = "World";
}
The relevant member of NestedStatic
type is referenced like:
<h1>Hello, @TwistedType.NestedStatic.ArrayOfTwistedType[0].World!</h1>
Expected Behavior
Type initialization should be successful in WASM as in server.
Steps To Reproduce
Clone this repo and run.
Versions:
- Chrome: 116.0.5829.0
- .net: 7.0.304
Exceptions (if any)
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: The type initializer for 'NestedStatic' threw an exception.
System.TypeInitializationException: The type initializer for 'NestedStatic' threw an exception.
---> System.TypeInitializationException: The type initializer for 'BlzWasmTypeInitRepro.TwistedType' threw an exception.
---> System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Prepend[TwistedType](IEnumerable`1 source, TwistedType element)
at BlzWasmTypeInitRepro.TwistedType..cctor() in BlzWasmTypeInitRepro\Types.cs:line 5
--- End of inner exception stack trace ---
at BlzWasmTypeInitRepro.TwistedType.NestedStatic..cctor() in BlzWasmTypeInitRepro\Types.cs:line 9
--- End of inner exception stack trace ---
at BlzWasmTypeInitRepro.Pages.Index.BuildRenderTree(RenderTreeBuilder __builder) in BlzWasmTypeInitRepro\Pages\Index.razor:line 3
at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
.NET Version
7.0.304
Anything else?
No response
Metadata
Metadata
Assignees
Labels
JitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triagearea-Codegen-meta-mononeeds-further-triageIssue has been initially triaged, but needs deeper consideration or reconsiderationIssue has been initially triaged, but needs deeper consideration or reconsideration
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
ghost commentedon Jul 24, 2023
Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.
Issue Details
Is there an existing issue for this?
Describe the bug
Type layout below causes
System.TypeInitializationException
to be thrown in WASM (same code can run in a server-type project):The relevant member of
NestedStatic
type is referenced like:Expected Behavior
Type initialization should be successful in WASM as in server.
Steps To Reproduce
Clone this repo and run.
Versions:
Exceptions (if any)
.NET Version
7.0.304
Anything else?
No response
arch-wasm
,untriaged
,area-VM-meta-mono
marek-safar commentedon Jul 24, 2023
/cc @lambdageek
lambdageek commentedon Jul 24, 2023
Repros in console app using mono as the runtime:
$ dotnet run --self-contained -p:UseMonoRuntime=true -r osx-arm64
At first glance, I think this might be allowed by ECMA you cannot depend on the order of execution for static constructors...
lambdageek commentedon Jul 24, 2023
CoreCLR is also quite fragile here. change
#if true
to#if false
below to see a difference - the first one runs, the second one throwslambdageek commentedon Jul 24, 2023
Hmm... comparing the IL for the working and broken versions of
FirstOne
, it looks like the working version hasbeforefieldinit
and the broken one doesn't.lambdageek commentedon Jul 24, 2023
Ok, this isn't one of the cases where ECMA allows us some leeway because of circular dependencies. Rather, this is a case where the cctor must run "at or before static field access" and mono is leaning on the "or before" (specifically I think we run it when the instance constructor for
FirstOne
is called)It looks like mono is calling a
beforefieldinit
static constructor even if we never touch the static fields of that classIt looks like we're running the cctor for
FirstOne
whenSecondOne
tries to instantiate it. But constructor invocation for abeforefieldinit
class is not sufficient. Only static field access (or explicit cctor invocation) should trigger it, I think.There is a variant where instead of calling the instance constructor, we call a static method from
FirstOne
. In this case, too, CoreCLR doesn't call the cctor forFirstOne
4 remaining items
vargaz commentedon Jul 24, 2023
Probably a dup of:
#77513
lambdageek commentedon Jul 24, 2023
I think #77513 is not quite the same. In that one, the bad static field is used in the body of a called method - it's just not on an executed path. In this one, the bad static field is not used at all in any JITted method.
Fixing 77513 seems harder
LeVladIonescu commentedon Aug 14, 2023
Moving this to
Postponed to .Net9
with high priority.Internal.Runtime.Augments.DynamicDelegateAugments
in build scenarios without linking #90519