Skip to content

Commit b9bd06b

Browse files
committed
Typemaps use type token ids again
1 parent c853ea1 commit b9bd06b

File tree

9 files changed

+84
-30
lines changed

9 files changed

+84
-30
lines changed

src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ internal static class RuntimeNativeMethods
9393
internal static extern IntPtr clr_typemap_managed_to_java (string fullName, IntPtr mvid);
9494

9595
[DllImport (RuntimeConstants.InternalDllName, CallingConvention = CallingConvention.Cdecl)]
96-
internal static extern IntPtr clr_typemap_java_to_managed (string fullName);
96+
internal static extern bool clr_typemap_java_to_managed (string java_type_name, out IntPtr managed_assembly_name, out uint managed_type_token_id);
9797

9898
[MethodImplAttribute(MethodImplOptions.InternalCall)]
9999
internal static extern void monodroid_unhandled_exception (Exception javaException);

src/Mono.Android/Java.Interop/TypeManager.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,17 +220,24 @@ static Type monovm_typemap_java_to_managed (string java_type_name)
220220
return monodroid_typemap_java_to_managed (java_type_name);
221221
}
222222

223-
[UnconditionalSuppressMessage ("Trimming", "IL2057", Justification = "Value of java_type_name isn't statically known.")]
223+
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Value of java_type_name isn't statically known.")]
224224
static Type? clr_typemap_java_to_managed (string java_type_name)
225225
{
226-
IntPtr managedTypeNamePointer = RuntimeNativeMethods.clr_typemap_java_to_managed (java_type_name);
227-
if (managedTypeNamePointer == IntPtr.Zero) {
226+
bool result = RuntimeNativeMethods.clr_typemap_java_to_managed (java_type_name, out IntPtr managedAssemblyNamePointer, out uint managedTypeTokenId);
227+
if (!result || managedAssemblyNamePointer == IntPtr.Zero) {
228228
return null;
229229
}
230230

231-
string managedTypeName = Marshal.PtrToStringAnsi (managedTypeNamePointer);
232-
Logger.Log (LogLevel.Info, "monodroid", $"clr_typemap_java_to_managed ('{java_type_name}') returned '{managedTypeName}'");
233-
Type ret = Type.GetType (managedTypeName);
231+
string managedAssemblyName = Marshal.PtrToStringAnsi (managedAssemblyNamePointer);
232+
Assembly assembly = Assembly.Load (managedAssemblyName);
233+
Type? ret = null;
234+
foreach (Module module in assembly.Modules) {
235+
ret = module.ResolveType ((int)managedTypeTokenId);
236+
if (ret != null) {
237+
break;
238+
}
239+
}
240+
234241
Logger.Log (LogLevel.Info, "monodroid", $"Loaded type: {ret}");
235242
return ret;
236243
}

src/Xamarin.Android.Build.Tasks/Utilities/TypeMappingReleaseNativeAssemblyGeneratorCLR.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ sealed class TypeMapJava
173173
[NativeAssembler (UsesDataProvider = true)]
174174
public uint managed_type_name_index;
175175

176+
[NativeAssembler (NumberFormat = LlvmIrVariableNumberFormat.Hexadecimal)]
177+
public uint managed_type_token_id;
178+
176179
[NativeAssembler (UsesDataProvider = true)]
177180
public uint java_name_index;
178181
}
@@ -398,15 +401,15 @@ void InitJavaMap (ConstructionState cs)
398401
TypeMapJava map_entry;
399402
foreach (TypeMapGenerator.TypeMapReleaseEntry entry in mappingData.JavaTypes) {
400403
string assemblyName = mappingData.Modules[entry.ModuleIndex].AssemblyName;
401-
string fullManagedTypeName = $"{entry.ManagedTypeName}, {assemblyName}";
402-
uint managedTypeNameIndex = GetEntryIndex (fullManagedTypeName, seenManagedTypeNames, cs.ManagedTypeNames);
404+
uint managedTypeNameIndex = GetEntryIndex (entry.ManagedTypeName, seenManagedTypeNames, cs.ManagedTypeNames);
403405
cs.JavaNames.Add (entry.JavaName);
404406

405407
map_entry = new TypeMapJava {
406408
ManagedTypeName = cs.ManagedTypeNames[(int)managedTypeNameIndex],
407409

408410
module_index = (uint)entry.ModuleIndex, // UInt32.MaxValue,
409411
managed_type_name_index = managedTypeNameIndex,
412+
managed_type_token_id = entry.Token,
410413
java_name_index = (uint)(cs.JavaNames.Count - 1),
411414
JavaName = entry.JavaName,
412415
};

src/native/clr/host/internal-pinvokes.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ const char* clr_typemap_managed_to_java (const char *typeName, const uint8_t *mv
2828
return TypeMapper::typemap_managed_to_java (typeName, mvid);
2929
}
3030

31-
const char* clr_typemap_java_to_managed (const char *typeName) noexcept
31+
bool clr_typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept
3232
{
33-
return TypeMapper::typemap_java_to_managed (typeName);
33+
return TypeMapper::typemap_java_to_managed (java_type_name, assembly_name, managed_type_token_id);
3434
}
3535

3636
void monodroid_log (LogLevel level, LogCategories category, const char *message) noexcept

src/native/clr/host/typemap.cc

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <host/typemap.hh>
44
#include <runtime-base/timing-internal.hh>
55
#include <runtime-base/search.hh>
6+
#include <runtime-base/util.hh>
67
#include <shared/xxhash.hh>
78
#include <xamarin-app.hh>
89

@@ -14,10 +15,6 @@ namespace {
1415
static inline constexpr size_t MVID_SIZE = 16;
1516
static inline constexpr size_t NUM_HYPHENS = 4;
1617
static inline constexpr size_t BUF_SIZE = (MVID_SIZE * 2) + NUM_HYPHENS + 1;
17-
static inline std::array<char, 16> hex_map {
18-
'0', '1', '2', '3', '4', '5', '6', '7',
19-
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
20-
};
2118

2219
public:
2320
explicit MonoGuidString (const uint8_t *mvid) noexcept
@@ -29,8 +26,8 @@ namespace {
2926

3027
// In the caller we trust, we have no way to validate the size here
3128
auto to_hex = [this, &mvid] (size_t &dest_idx, size_t src_idx) {
32-
_ascii_form[dest_idx++] = hex_map[(mvid[src_idx] & 0xf0) >> 4];
33-
_ascii_form[dest_idx++] = hex_map[mvid[src_idx] & 0x0f];
29+
Util::to_hex (mvid[src_idx], _ascii_form[dest_idx], _ascii_form[dest_idx + 1]);
30+
dest_idx += 2;
3431
};
3532

3633
auto hyphen = [this] (size_t &dest_idx) {
@@ -240,7 +237,7 @@ auto TypeMapper::typemap_managed_to_java (const char *typeName, const uint8_t *m
240237

241238
#if defined(DEBUG)
242239
[[gnu::flatten]]
243-
auto TypeMapper::typemap_java_to_managed (const char *typeName) noexcept -> const char*
240+
auto TypeMapper::typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept -> bool
244241
{
245242
Helpers::abort_application ("typemap_java_to_managed not implemented for debug builds yet");
246243
}
@@ -258,32 +255,65 @@ auto TypeMapper::find_java_to_managed_entry (hash_t name_hash) noexcept -> const
258255
}
259256

260257
[[gnu::flatten]]
261-
auto TypeMapper::typemap_java_to_managed (const char *typeName) noexcept -> const char*
258+
auto TypeMapper::typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept -> bool
262259
{
263-
if (typeName == nullptr) [[unlikely]] {
264-
return nullptr;
260+
if (java_type_name == nullptr || assembly_name == nullptr || managed_type_token_id == nullptr) [[unlikely]] {
261+
if (java_type_name == nullptr) {
262+
log_warn (
263+
LOG_ASSEMBLY,
264+
"typemap: required parameter `{}` not passed to {}",
265+
"java_type_name"sv,
266+
__PRETTY_FUNCTION__
267+
);
268+
}
269+
270+
if (assembly_name == nullptr) {
271+
log_warn (
272+
LOG_ASSEMBLY,
273+
"typemap: required parameter `{}` not passed to {}",
274+
"assembly_name"sv,
275+
__PRETTY_FUNCTION__
276+
);
277+
}
278+
279+
if (managed_type_token_id == nullptr) {
280+
log_warn (
281+
LOG_ASSEMBLY,
282+
"typemap: required parameter `{}` not passed to {}",
283+
"managed_type_token_id"sv,
284+
__PRETTY_FUNCTION__
285+
);
286+
}
287+
288+
return false;
265289
}
266290

267-
hash_t name_hash = xxhash::hash (typeName, strlen (typeName));
291+
hash_t name_hash = xxhash::hash (java_type_name, strlen (java_type_name));
268292
TypeMapJava const* java_entry = find_java_to_managed_entry (name_hash);
269293
if (java_entry == nullptr) {
270294
log_info (
271295
LOG_ASSEMBLY,
272296
"typemap: unable to find mapping to a managed type from Java type '{}' (hash {:x})",
273-
optional_string (typeName),
297+
optional_string (java_type_name),
274298
name_hash
275299
);
276300

277-
return nullptr;
301+
return false;
278302
}
279303

304+
TypeMapModule const &module = managed_to_java_map[java_entry->module_index];
305+
*assembly_name = managed_assembly_names[module.assembly_name_index];
306+
*managed_type_token_id = java_entry->managed_type_token_id;
307+
280308
log_debug (
281309
LOG_ASSEMBLY,
282-
"Java type '{}' corresponds to managed type '{}' ({:p}",
283-
optional_string (typeName),
310+
"Java type '{}' corresponds to managed type '{}' (token 0x{:x} in assembly '{}')",
311+
optional_string (java_type_name),
284312
optional_string (managed_type_names[java_entry->managed_type_name_index]),
285-
reinterpret_cast<const void*>(managed_type_names[java_entry->managed_type_name_index])
313+
*managed_type_token_id,
314+
optional_string (*assembly_name)
286315
);
287-
return managed_type_names[java_entry->managed_type_name_index];
316+
317+
return true;
288318
}
289319
#endif // ndef DEBUG

src/native/clr/include/host/typemap.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace xamarin::android {
1111
{
1212
public:
1313
static auto typemap_managed_to_java (const char *typeName, const uint8_t *mvid) noexcept -> const char*;
14-
static auto typemap_java_to_managed (const char *typeName) noexcept -> const char*;
14+
static auto typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_doken_id) noexcept -> bool;
1515

1616
private:
1717
#if defined(RELEASE)

src/native/clr/include/runtime-base/internal-pinvokes.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void _monodroid_gref_log (const char *message) noexcept;
99
int _monodroid_gref_log_new (jobject curHandle, char curType, jobject newHandle, char newType, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
1010
void _monodroid_gref_log_delete (jobject handle, char type, const char *threadName, int threadId, const char *from, int from_writable) noexcept;
1111
const char* clr_typemap_managed_to_java (const char *typeName, const uint8_t *mvid) noexcept;
12-
const char* clr_typemap_java_to_managed (const char *typeName) noexcept;
12+
bool clr_typemap_java_to_managed (const char *java_type_name, char const** assembly_name, uint32_t *managed_type_token_id) noexcept;
1313
void monodroid_log (xamarin::android::LogLevel level, LogCategories category, const char *message) noexcept;
1414
char* monodroid_TypeManager_get_java_class_name (jclass klass) noexcept;
1515
void monodroid_free (void *ptr) noexcept;

src/native/clr/include/runtime-base/util.hh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,25 @@ namespace xamarin::android {
4141

4242
class Util
4343
{
44+
static constexpr inline std::array<char, 16> hex_map {
45+
'0', '1', '2', '3', '4', '5', '6', '7',
46+
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
47+
};
48+
4449
public:
4550
static int create_directory (const char *pathname, mode_t mode);
4651
static void create_public_directory (std::string_view const& dir);
4752
static auto monodroid_fopen (std::string_view const& filename, std::string_view const& mode) noexcept -> FILE*;
4853
static void set_world_accessable (std::string_view const& path);
4954

55+
// Puts higher half of the `value` byte as a hexadecimal character in `high_half` and
56+
// the lower half in `low_half`
57+
static void to_hex (uint8_t value, char &high_half, char &low_half) noexcept
58+
{
59+
high_half = hex_map[(value & 0xf0) >> 4];
60+
low_half = hex_map[value & 0x0f];
61+
}
62+
5063
static auto should_log (LogCategories category) noexcept -> bool
5164
{
5265
return (log_categories & category) != 0;

src/native/clr/include/xamarin-app.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct TypeMapJava
9393
{
9494
uint32_t module_index;
9595
uint32_t managed_type_name_index;
96+
uint32_t managed_type_token_id;
9697
uint32_t java_name_index;
9798
};
9899
#endif

0 commit comments

Comments
 (0)