Skip to content

Commit

Permalink
[mono] Prefix exported symbols via UnmanagedCallersOnly attribute (#7…
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanpovazan authored Jan 19, 2023
1 parent b62bbdd commit f429780
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -5208,9 +5208,9 @@ MONO_RESTORE_WARNING
for (j = 0; j < decoded_args->named_args_num; ++j) {
if (decoded_args->named_args_info [j].field && !strcmp (decoded_args->named_args_info [j].field->name, "EntryPoint")) {
named = (const char *)decoded_args->named_args[j]->value.primitive;
slen = mono_metadata_decode_value (named, &named);
slen = mono_metadata_decode_value (named, &named) + (int)strlen(acfg->user_symbol_prefix);
export_name = (char *)g_malloc (slen + 1);
memcpy (export_name, named, slen);
sprintf (export_name, "%s%s", acfg->user_symbol_prefix, named);
export_name [slen] = 0;
}
}
Expand All @@ -5222,7 +5222,7 @@ MONO_RESTORE_WARNING
add_method (acfg, wrapper);
if (export_name) {
g_hash_table_insert (acfg->export_names, wrapper, export_name);
g_string_append_printf (export_symbols, "%s%s\n", acfg->user_symbol_prefix, export_name);
g_string_append_printf (export_symbols, "%s\n", export_name);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<linker>
<!-- this is here to show how to configure the trimming -->
<assembly fullname="iOS.Device.ExportManagedSymbols.Test">
<type fullname="Program">
<method name="ManagedMethod" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

public static class Program
{
[DllImport("__Internal")]
public static extern void mono_ios_set_summary (string value);

[UnmanagedCallersOnly(EntryPoint="exposed_managed_method")]
public static int ManagedMethod() => 42;

public static async Task<int> Main(string[] args)
{
mono_ios_set_summary($"Starting functional test");
Console.WriteLine("Done!");
await Task.Delay(5000);

return 42;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk" TreatAsLocalProperty="MonoForceInterpreter">

<PropertyGroup>
<OutputType>Exe</OutputType>
<MonoForceInterpreter>false</MonoForceInterpreter>
<RunAOTCompilation>true</RunAOTCompilation>
<TestRuntime>true</TestRuntime>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TargetOS Condition="'$(TargetOS)' == ''">iOS</TargetOS>
<MainLibraryFileName>iOS.Device.ExportManagedSymbols.Test.dll</MainLibraryFileName>
<IncludesTestRunner>false</IncludesTestRunner>
<ExpectedExitCode>42</ExpectedExitCode>
<EnableAggressiveTrimming>true</EnableAggressiveTrimming>
<MonoEnableLLVM>true</MonoEnableLLVM>
<NativeMainSource>$(MSBuildProjectDirectory)/main.m</NativeMainSource>
</PropertyGroup>

<ItemGroup>
<Compile Include="Program.cs" />
<!-- Prevent trimming of the exposed managed method via ILLinker -->
<TrimmerRootDescriptor Include="$(MSBuildProjectDirectory)/ILLink.Descriptors.xml" />
</ItemGroup>
</Project>
106 changes: 106 additions & 0 deletions src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#import <UIKit/UIKit.h>
#import <dlfcn.h>
#import "runtime.h"
#include <TargetConditionals.h>

@interface ViewController : UIViewController
@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *controller;
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = self.controller;
[self.window makeKeyAndVisible];
return YES;
}
@end

UILabel *summaryLabel;
UITextView* logLabel;

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

CGRect applicationFrame = [[UIScreen mainScreen] bounds];
logLabel = [[UITextView alloc] initWithFrame:
CGRectMake(2.0, 50.0, applicationFrame.size.width - 2.0, applicationFrame.size.height - 50.0)];
logLabel.font = [UIFont systemFontOfSize:9.0];
logLabel.backgroundColor = [UIColor blackColor];
logLabel.textColor = [UIColor greenColor];
logLabel.scrollEnabled = YES;
logLabel.alwaysBounceVertical = YES;
#ifndef TARGET_OS_TV
logLabel.editable = NO;
#endif
logLabel.clipsToBounds = YES;

summaryLabel = [[UILabel alloc] initWithFrame: CGRectMake(10.0, 0.0, applicationFrame.size.width - 10.0, 50)];
summaryLabel.textColor = [UIColor whiteColor];
summaryLabel.font = [UIFont boldSystemFontOfSize: 12];
summaryLabel.numberOfLines = 2;
summaryLabel.textAlignment = NSTextAlignmentLeft;
#if !TARGET_OS_SIMULATOR || FORCE_AOT
summaryLabel.text = @"Loading...";
#else
summaryLabel.text = @"Jitting...";
#endif
[self.view addSubview:logLabel];
[self.view addSubview:summaryLabel];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
void *del = dlsym (RTLD_DEFAULT, "exposed_managed_method");
NSAssert(del != NULL, @"'exposed_managed_method' not found");
mono_ios_runtime_init ();
});
}

@end

// called from C#
void
invoke_external_native_api (void (*callback)(void))
{
if (callback)
callback();
}

// can be called from C# to update UI
void
mono_ios_set_summary (const char* value)
{
NSString* nsstr = [NSString stringWithUTF8String:value];
dispatch_async(dispatch_get_main_queue(), ^{
summaryLabel.text = nsstr;
});
}

// can be called from C# to update UI
void
mono_ios_append_output (const char* value)
{
NSString* nsstr = [NSString stringWithUTF8String:value];
dispatch_async(dispatch_get_main_queue(), ^{
logLabel.text = [logLabel.text stringByAppendingString:nsstr];
CGRect caretRect = [logLabel caretRectForPosition:logLabel.endOfDocument];
[logLabel scrollRectToVisible:caretRect animated:NO];
[logLabel setScrollEnabled:NO];
[logLabel setScrollEnabled:YES];
});
}

int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

0 comments on commit f429780

Please sign in to comment.