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

[hot_reload] Add support for row modifications; CustomAttribute updates #55445

Merged
merged 7 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;


namespace System.Reflection.Metadata.ApplyUpdate.Test
{
[AttributeUsage (AttributeTargets.Method, AllowMultiple=true)]
public class MyAttribute : Attribute
{
public MyAttribute (string stringValue) { StringValue = stringValue; }

public MyAttribute (Type typeValue) { TypeValue = typeValue; }

public MyAttribute (int x) { IntValue = x; }

public string StringValue { get; set; }
public Type TypeValue {get; set; }
public int IntValue {get; set; }
}

public class ClassWithCustomAttributeUpdates
{
[MyAttribute ("abcd")]
public static string Method1 () => null;

[MyAttribute (typeof(Exception))]
public static string Method2 () => null;

[MyAttribute (42, StringValue = "hijkl", TypeValue = typeof(Type))]
[MyAttribute (17, StringValue = "", TypeValue = typeof(object))]
public static string Method3 () => null;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;


namespace System.Reflection.Metadata.ApplyUpdate.Test
{
[AttributeUsage (AttributeTargets.Method, AllowMultiple=true)]
public class MyAttribute : Attribute
{
public MyAttribute (string stringValue) { StringValue = stringValue; }

public MyAttribute (Type typeValue) { TypeValue = typeValue; }

public MyAttribute (int x) { IntValue = x; }

public string StringValue { get; set; }
public Type TypeValue {get; set; }
public int IntValue {get; set; }
}

public class ClassWithCustomAttributeUpdates
{
[MyAttribute ("rstuv")]
public static string Method1 () => null;

[MyAttribute (typeof(ArgumentException))]
public static string Method2 () => null;

[MyAttribute (2042, StringValue = "qwerty", TypeValue = typeof(byte[]))]
[MyAttribute (17, StringValue = "", TypeValue = typeof(object))]
public static string Method3 () => null;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>System.Runtime.Loader.Tests</RootNamespace>
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
<TestRuntime>true</TestRuntime>
<DeltaScript>deltascript.json</DeltaScript>
</PropertyGroup>
<ItemGroup>
<Compile Include="CustomAttributeUpdate.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"changes": [
{"document": "CustomAttributeUpdate.cs", "update": "CustomAttributeUpdate_v1.cs"},
]
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<TestRuntime>true</TestRuntime>
<DeltaScript>deltascript.json</DeltaScript>
<SkipTestUtilitiesReference>true</SkipTestUtilitiesReference>
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="MethodBody1.cs" />
Expand Down
29 changes: 29 additions & 0 deletions src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ void ClassWithCustomAttributes()
});
}

[ConditionalFact(typeof(ApplyUpdateUtil), nameof (ApplyUpdateUtil.IsSupported))]
public void CustomAttributeUpdates()
{
// Test that _modifying_ custom attribute constructor/property argumments works as expected.
// For this test, we don't change which constructor is called, or how many custom attributes there are.
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributeUpdates).Assembly;

ApplyUpdateUtil.ApplyUpdate(assm);
ApplyUpdateUtil.ClearAllReflectionCaches();

// Just check the updated value on one method

Type attrType = typeof(System.Reflection.Metadata.ApplyUpdate.Test.MyAttribute);
Type ty = assm.GetType("System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributeUpdates");
Assert.NotNull(ty);
MethodInfo mi = ty.GetMethod(nameof(System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributeUpdates.Method1), BindingFlags.Public | BindingFlags.Static);
Assert.NotNull(mi);
var cattrs = Attribute.GetCustomAttributes(mi, attrType);
Assert.NotNull(cattrs);
Assert.Equal(1, cattrs.Length);
Assert.NotNull(cattrs[0]);
Assert.Equal(attrType, cattrs[0].GetType());
string p = (cattrs[0] as System.Reflection.Metadata.ApplyUpdate.Test.MyAttribute).StringValue;
Assert.Equal("rstuv", p);
});
}

class NonRuntimeAssembly : Assembly
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<ProjectReference Include="LoaderLinkTest.Dynamic\LoaderLinkTest.Dynamic.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.MethodBody1\System.Reflection.Metadata.ApplyUpdate.Test.MethodBody1.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributes\System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributes.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.CustomAttributeUpdate\System.Reflection.Metadata.ApplyUpdate.Test.CustomAttributeUpdate.csproj" />

</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'Browser'">
Expand All @@ -58,6 +59,9 @@
<TrimmerRootAssembly
Condition="$([System.String]::Copy('%(ResolvedFileToPublish.FileName)%(ResolvedFileToPublish.Extension)').EndsWith('System.Reflection.Metadata.ApplyUpdate.Test.ClassWithCustomAttributes.dll'))"
Include="%(ResolvedFileToPublish.FullPath)" />
<TrimmerRootAssembly
Condition="$([System.String]::Copy('%(ResolvedFileToPublish.FileName)%(ResolvedFileToPublish.Extension)').EndsWith('System.Reflection.Metadata.ApplyUpdate.Test.CustomAttributeUpdate.dll'))"
Include="%(ResolvedFileToPublish.FullPath)" />
</ItemGroup>
</Target>

Expand Down
9 changes: 9 additions & 0 deletions src/mono/mono/component/hot_reload-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ hot_reload_stub_table_bounds_check (MonoImage *base_image, int table_index, int
static gboolean
hot_reload_stub_delta_heap_lookup (MonoImage *base_image, MetadataHeapGetterFunc get_heap, uint32_t orig_index, MonoImage **image_out, uint32_t *index_out);

static gboolean
hot_reload_stub_has_modified_rows (const MonoTableInfo *table);

static MonoComponentHotReload fn_table = {
{ MONO_COMPONENT_ITF_VERSION, &hot_reload_stub_available },
&hot_reload_stub_set_fastpath_data,
Expand All @@ -75,6 +78,7 @@ static MonoComponentHotReload fn_table = {
&hot_reload_stub_get_updated_method_rva,
&hot_reload_stub_table_bounds_check,
&hot_reload_stub_delta_heap_lookup,
&hot_reload_stub_has_modified_rows,
};

static bool
Expand Down Expand Up @@ -172,6 +176,11 @@ hot_reload_stub_delta_heap_lookup (MonoImage *base_image, MetadataHeapGetterFunc
g_assert_not_reached ();
}

static gboolean
hot_reload_stub_has_modified_rows (const MonoTableInfo *table){
return FALSE;
}

MONO_COMPONENT_EXPORT_ENTRYPOINT
MonoComponentHotReload *
mono_component_hot_reload_init (void)
Expand Down
Loading