diff --git a/Source/Editor/Cooker/Steps/DeployDataStep.cpp b/Source/Editor/Cooker/Steps/DeployDataStep.cpp index 7c8b599c6..d4978cb33 100644 --- a/Source/Editor/Cooker/Steps/DeployDataStep.cpp +++ b/Source/Editor/Cooker/Steps/DeployDataStep.cpp @@ -26,6 +26,9 @@ bool DeployDataStep::Perform(CookingData& data) Platform::Sleep(10); } FileSystem::CreateDirectory(contentDir); +#if USE_NETCORE + // TODO: Optionally copy all files needed for self-contained deployment +#else const auto srcMono = depsRoot / TEXT("Mono"); const auto dstMono = data.DataOutputPath / TEXT("Mono"); if (!FileSystem::DirectoryExists(dstMono)) @@ -42,6 +45,7 @@ bool DeployDataStep::Perform(CookingData& data) return true; } } +#endif // Deploy engine data for the target platform if (data.Tools->OnDeployBinaries(data)) diff --git a/Source/Editor/CustomEditors/CustomEditor.cs b/Source/Editor/CustomEditors/CustomEditor.cs index 1b4b3e013..1f13decd5 100644 --- a/Source/Editor/CustomEditors/CustomEditor.cs +++ b/Source/Editor/CustomEditors/CustomEditor.cs @@ -616,7 +616,14 @@ namespace FlaxEditor.CustomEditors else { // Default - obj = JsonConvert.DeserializeObject(text, TypeUtils.GetType(Values.Type), JsonSerializer.Settings); + try + { + obj = JsonConvert.DeserializeObject(text, TypeUtils.GetType(Values.Type), JsonSerializer.Settings); + } + catch + { + obj = null; + } } if (obj == null || Values.Type.IsInstanceOfType(obj)) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index a20af8490..0c1f93864 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -15,6 +15,7 @@ using System.Runtime.InteropServices.Marshalling; using FlaxEngine.Visject; using System.Buffers; using System.Collections.Concurrent; +using System.Text; #pragma warning disable 1591 @@ -181,9 +182,11 @@ namespace FlaxEngine return managedArray; } - internal static ManagedArray AllocateNewArray(T* ptr, int length) where T : unmanaged => new ManagedArray(ptr, length, Unsafe.SizeOf()); + internal static ManagedArray AllocateNewArray(int length, int elementSize) + => new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, elementSize), length, elementSize); - internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, int elementSize) => new ManagedArray(ptr.ToPointer(), length, elementSize); + internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, int elementSize) + => new ManagedArray(ptr, length, elementSize); /// /// Returns an instance of ManagedArray from shared pool. @@ -198,6 +201,19 @@ namespace FlaxEngine return managedArray; } + /// + /// Returns an instance of ManagedArray from shared pool. + /// + /// + /// The resources must be released by calling FreePooled() instead of Free()-method. + /// + internal static ManagedArray AllocatePooledArray(int length) where T : unmanaged + { + ManagedArray managedArray = ManagedArrayPool.Get(); + managedArray.Allocate((IntPtr)NativeInterop.NativeAlloc(length, Unsafe.SizeOf()), length, Unsafe.SizeOf()); + return managedArray; + } + internal ManagedArray(Array arr) => WrapArray(arr); internal void WrapArray(Array arr) @@ -224,7 +240,7 @@ namespace FlaxEngine private ManagedArray() { } - private ManagedArray(void* ptr, int length, int elementSize) => Allocate(new IntPtr(ptr), length, elementSize); + private ManagedArray(IntPtr ptr, int length, int elementSize) => Allocate(ptr, length, elementSize); ~ManagedArray() { @@ -242,7 +258,7 @@ namespace FlaxEngine } if (unmanagedData != IntPtr.Zero) { - Marshal.FreeHGlobal(unmanagedData); + NativeInterop.NativeFree(unmanagedData.ToPointer()); unmanagedData = IntPtr.Zero; } } @@ -608,7 +624,7 @@ namespace FlaxEngine return null; } numElements = managed.Length; - ManagedArray managedArray = ManagedArray.AllocatePooledArray((TUnmanagedElement*)Marshal.AllocHGlobal(sizeof(TUnmanagedElement) * managed.Length), managed.Length); + ManagedArray managedArray = ManagedArray.AllocatePooledArray(managed.Length); var ptr = GCHandle.ToIntPtr(GCHandle.Alloc(managedArray)); return (TUnmanagedElement*)ptr; } @@ -644,7 +660,7 @@ namespace FlaxEngine if (managed == null) return; managedArray = managed; - unmanagedArray = ManagedArray.AllocatePooledArray((TUnmanagedElement*)Marshal.AllocHGlobal(sizeof(TUnmanagedElement) * managed.Length), managed.Length); + unmanagedArray = ManagedArray.AllocatePooledArray(managed.Length); handle = GCHandle.Alloc(unmanagedArray); } @@ -692,7 +708,7 @@ namespace FlaxEngine return null; } numElements = managed.Length; - ManagedArray managedArray = ManagedArray.AllocatePooledArray((TUnmanagedElement*)Marshal.AllocHGlobal(sizeof(TUnmanagedElement) * managed.Length), managed.Length); + ManagedArray managedArray = ManagedArray.AllocatePooledArray(managed.Length); IntPtr handle = GCHandle.ToIntPtr(GCHandle.Alloc(managedArray)); return (TUnmanagedElement*)handle; } @@ -869,6 +885,35 @@ namespace FlaxEngine nativeLibraryPaths[moduleName] = modulePath; } + internal static void* NativeAlloc(int byteCount) + { + return NativeMemory.AlignedAlloc((UIntPtr)byteCount, 16); + } + + internal static void* NativeAlloc(int elementCount, int elementSize) + { + return NativeMemory.AlignedAlloc((UIntPtr)(elementCount * elementSize), 16); + } + + internal static IntPtr NativeAllocStringAnsi(string str) + { + if (str is null) + return IntPtr.Zero; + + int length = str.Length + 1; + void* ptr = NativeMemory.AlignedAlloc((UIntPtr)length, 16); + Span byteSpan = new Span(ptr, length); + Encoding.ASCII.GetBytes(str, byteSpan); + byteSpan[length - 1] = 0; + + return (IntPtr)ptr; + } + + internal static void NativeFree(void* ptr) + { + NativeMemory.AlignedFree(ptr); + } + internal static T[] GCHandleArrayToManagedArray(ManagedArray ptrArray) { Span span = ptrArray.GetSpan(); @@ -1530,7 +1575,7 @@ namespace FlaxEngine Assembly assembly = Unsafe.As(GCHandle.FromIntPtr(assemblyHandle).Target); var assemblyTypes = GetAssemblyTypes(assembly); - NativeClassDefinitions* arr = (NativeClassDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf() * assemblyTypes.Length).ToPointer(); + NativeClassDefinitions* arr = (NativeClassDefinitions*)NativeAlloc(assemblyTypes.Length, Unsafe.SizeOf()); for (int i = 0; i < assemblyTypes.Length; i++) { @@ -1545,9 +1590,9 @@ namespace FlaxEngine NativeClassDefinitions managedClass = new NativeClassDefinitions() { typeHandle = GCHandle.ToIntPtr(typeHandle), - name = Marshal.StringToCoTaskMemAnsi(type.Name), - fullname = Marshal.StringToCoTaskMemAnsi(type.FullName), - @namespace = Marshal.StringToCoTaskMemAnsi(type.Namespace ?? ""), + name = NativeAllocStringAnsi(type.Name), + fullname = NativeAllocStringAnsi(type.FullName), + @namespace = NativeAllocStringAnsi(type.Namespace ?? ""), typeAttributes = (uint)type.Attributes, }; Unsafe.Write(ptr.ToPointer(), managedClass); @@ -1565,9 +1610,9 @@ namespace FlaxEngine *managedClass = new NativeClassDefinitions() { typeHandle = GCHandle.ToIntPtr(classTypeHandle), - name = Marshal.StringToCoTaskMemAnsi(type.Name), - fullname = Marshal.StringToCoTaskMemAnsi(type.FullName), - @namespace = Marshal.StringToCoTaskMemAnsi(type.Namespace ?? ""), + name = NativeAllocStringAnsi(type.Name), + fullname = NativeAllocStringAnsi(type.FullName), + @namespace = NativeAllocStringAnsi(type.Namespace ?? ""), typeAttributes = (uint)type.Attributes, }; *assemblyHandle = GCHandle.ToIntPtr(GetAssemblyHandle(type.Assembly)); @@ -1586,13 +1631,13 @@ namespace FlaxEngine foreach (MethodInfo method in instanceMethods) methods.Add(method); - NativeMethodDefinitions* arr = (NativeMethodDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf() * methods.Count).ToPointer(); + NativeMethodDefinitions* arr = (NativeMethodDefinitions*)NativeAlloc(methods.Count, Unsafe.SizeOf()); for (int i = 0; i < methods.Count; i++) { IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i); NativeMethodDefinitions classMethod = new NativeMethodDefinitions() { - name = Marshal.StringToCoTaskMemAnsi(methods[i].Name), + name = NativeAllocStringAnsi(methods[i].Name), numParameters = methods[i].GetParameters().Length, methodAttributes = (uint)methods[i].Attributes, }; @@ -1621,11 +1666,9 @@ namespace FlaxEngine Type type = Unsafe.As(GCHandle.FromIntPtr(typeHandle).Target); var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - NativeFieldDefinitions* arr = (NativeFieldDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf() * fields.Length).ToPointer(); + NativeFieldDefinitions* arr = (NativeFieldDefinitions*)NativeAlloc(fields.Length, Unsafe.SizeOf()); for (int i = 0; i < fields.Length; i++) { - IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i); - FieldHolder fieldHolder = new FieldHolder(fields[i], type); GCHandle fieldHandle = GCHandle.Alloc(fieldHolder); @@ -1636,12 +1679,12 @@ namespace FlaxEngine NativeFieldDefinitions classField = new NativeFieldDefinitions() { - name = Marshal.StringToCoTaskMemAnsi(fieldHolder.field.Name), + name = NativeAllocStringAnsi(fieldHolder.field.Name), fieldHandle = GCHandle.ToIntPtr(fieldHandle), fieldTypeHandle = GCHandle.ToIntPtr(GetTypeGCHandle(fieldHolder.field.FieldType)), fieldAttributes = (uint)fieldHolder.field.Attributes, }; - Unsafe.Write(ptr.ToPointer(), classField); + Unsafe.Write(IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i).ToPointer(), classField); } *classFields = arr; *classFieldsCount = fields.Length; @@ -1653,7 +1696,7 @@ namespace FlaxEngine Type type = Unsafe.As(GCHandle.FromIntPtr(typeHandle).Target); var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - NativePropertyDefinitions* arr = (NativePropertyDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf() * properties.Length).ToPointer(); + NativePropertyDefinitions* arr = (NativePropertyDefinitions*)NativeAlloc(properties.Length, Unsafe.SizeOf()); for (int i = 0; i < properties.Length; i++) { IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i); @@ -1663,7 +1706,7 @@ namespace FlaxEngine NativePropertyDefinitions classProperty = new NativePropertyDefinitions() { - name = Marshal.StringToCoTaskMemAnsi(properties[i].Name), + name = NativeAllocStringAnsi(properties[i].Name), }; if (getterMethod != null) { @@ -1688,7 +1731,7 @@ namespace FlaxEngine object[] attributeValues = type.GetCustomAttributes(false); Type[] attributeTypes = type.GetCustomAttributes(false).Select(x => x.GetType()).ToArray(); - NativeAttributeDefinitions* arr = (NativeAttributeDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf() * attributeTypes.Length).ToPointer(); + NativeAttributeDefinitions* arr = (NativeAttributeDefinitions*)NativeAlloc(attributeTypes.Length, Unsafe.SizeOf()); for (int i = 0; i < attributeTypes.Length; i++) { IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i); @@ -1702,7 +1745,7 @@ namespace FlaxEngine NativeAttributeDefinitions classAttribute = new NativeAttributeDefinitions() { - name = Marshal.StringToCoTaskMemAnsi(attributeTypes[i].Name), + name = NativeAllocStringAnsi(attributeTypes[i].Name), attributeTypeHandle = GCHandle.ToIntPtr(attributeTypeHandle), attributeHandle = GCHandle.ToIntPtr(attributeHandle), }; @@ -1733,13 +1776,11 @@ namespace FlaxEngine //foreach (Type interfaceType in type.BaseType.GetInterfaces()) // interfaces.Remove(interfaceType.FullName); - IntPtr arr = Marshal.AllocCoTaskMem(IntPtr.Size * interfaces.Length); + IntPtr arr = (IntPtr)NativeAlloc(interfaces.Length, IntPtr.Size); for (int i = 0; i < interfaces.Length; i++) { - IntPtr ptr = IntPtr.Add(arr, IntPtr.Size * i); - GCHandle handle = GetTypeGCHandle(interfaces[i]); - Marshal.WriteIntPtr(ptr, GCHandle.ToIntPtr(handle)); + Unsafe.Write(IntPtr.Add(arr, IntPtr.Size * i).ToPointer(), GCHandle.ToIntPtr(handle)); } *classInterfaces = arr; *classInterfacesCount = interfaces.Length; @@ -1759,11 +1800,11 @@ namespace FlaxEngine { MethodHolder methodHolder = Unsafe.As(GCHandle.FromIntPtr(methodHandle).Target); Type returnType = methodHolder.method.ReturnType; - IntPtr arr = Marshal.AllocCoTaskMem(IntPtr.Size * methodHolder.parameterTypes.Length); + IntPtr arr = (IntPtr)NativeAlloc(methodHolder.parameterTypes.Length, IntPtr.Size); for (int i = 0; i < methodHolder.parameterTypes.Length; i++) { GCHandle typeHandle = GetTypeGCHandle(methodHolder.parameterTypes[i]); - Marshal.WriteIntPtr(IntPtr.Add(new IntPtr(arr), IntPtr.Size * i), GCHandle.ToIntPtr(typeHandle)); + Unsafe.Write(IntPtr.Add(new IntPtr(arr), IntPtr.Size * i).ToPointer(), GCHandle.ToIntPtr(typeHandle)); } *typeHandles = arr; } @@ -1847,7 +1888,7 @@ namespace FlaxEngine Type marshalledType = ArrayFactory.GetMarshalledType(type); if (marshalledType.IsValueType) { - ManagedArray managedArray = ManagedArray.AllocateNewArray(Marshal.AllocHGlobal(Marshal.SizeOf(marshalledType) * (int)size), (int)size, Marshal.SizeOf(marshalledType)); + ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, Marshal.SizeOf(marshalledType)); return GCHandle.ToIntPtr(GCHandle.Alloc(managedArray/*, GCHandleType.Weak*/)); } else @@ -2045,8 +2086,10 @@ namespace FlaxEngine return (bool)returnObject ? boolTruePtr : boolFalsePtr; else if (methodHolder.method.ReturnType == typeof(Type)) return GCHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As(returnObject))); - else if (methodHolder.method.ReturnType == typeof(object[])) - return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak)); + else if (methodHolder.method.ReturnType.IsArray && ArrayFactory.GetMarshalledType(methodHolder.method.ReturnType.GetElementType()) == methodHolder.method.ReturnType.GetElementType()) + return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnObject)), GCHandleType.Weak)); + else if (methodHolder.method.ReturnType.IsArray) + return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak)); else return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak)); } @@ -2109,8 +2152,8 @@ namespace FlaxEngine firstAssemblyLoaded = true; Assembly flaxEngineAssembly = AppDomain.CurrentDomain.GetAssemblies().First(x => x.GetName().Name == "FlaxEngine.CSharp"); - *assemblyName = Marshal.StringToCoTaskMemAnsi(flaxEngineAssembly.GetName().Name); - *assemblyFullName = Marshal.StringToCoTaskMemAnsi(flaxEngineAssembly.FullName); + *assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); return GCHandle.ToIntPtr(GetAssemblyHandle(flaxEngineAssembly)); } string assemblyPath = Marshal.PtrToStringAnsi(assemblyPath_); @@ -2118,8 +2161,8 @@ namespace FlaxEngine Assembly assembly = scriptingAssemblyLoadContext.LoadFromAssemblyPath(assemblyPath); NativeLibrary.SetDllImportResolver(assembly, NativeLibraryImportResolver); - *assemblyName = Marshal.StringToCoTaskMemAnsi(assembly.GetName().Name); - *assemblyFullName = Marshal.StringToCoTaskMemAnsi(assembly.FullName); + *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); return GCHandle.ToIntPtr(GetAssemblyHandle(assembly)); } @@ -2132,8 +2175,8 @@ namespace FlaxEngine firstAssemblyLoaded = true; Assembly flaxEngineAssembly = AppDomain.CurrentDomain.GetAssemblies().First(x => x.GetName().Name == "FlaxEngine.CSharp"); - *assemblyName = Marshal.StringToCoTaskMemAnsi(flaxEngineAssembly.GetName().Name); - *assemblyFullName = Marshal.StringToCoTaskMemAnsi(flaxEngineAssembly.FullName); + *assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); return GCHandle.ToIntPtr(GetAssemblyHandle(flaxEngineAssembly)); } @@ -2149,8 +2192,8 @@ namespace FlaxEngine // Assemblies loaded via streams have no Location: https://github.com/dotnet/runtime/issues/12822 AssemblyLocations.Add(assembly.FullName, assemblyPath); - *assemblyName = Marshal.StringToCoTaskMemAnsi(assembly.GetName().Name); - *assemblyFullName = Marshal.StringToCoTaskMemAnsi(assembly.FullName); + *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); return GCHandle.ToIntPtr(GetAssemblyHandle(assembly)); } @@ -2162,15 +2205,15 @@ namespace FlaxEngine if (assembly == null) assembly = scriptingAssemblyLoadContext.Assemblies.FirstOrDefault(x => x.GetName().Name == name); - *assemblyName = Marshal.StringToCoTaskMemAnsi(assembly.GetName().Name); - *assemblyFullName = Marshal.StringToCoTaskMemAnsi(assembly.FullName); + *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); return GCHandle.ToIntPtr(GetAssemblyHandle(assembly)); } [UnmanagedCallersOnly] internal static IntPtr GetRuntimeInformation() { - return Marshal.StringToCoTaskMemAnsi(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription); + return NativeAllocStringAnsi(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription); } [UnmanagedCallersOnly] diff --git a/Source/Engine/Engine/NativeInterop_Invoker.cs b/Source/Engine/Engine/NativeInterop_Invoker.cs index ccbe468d9..5e02cbf14 100644 --- a/Source/Engine/Engine/NativeInterop_Invoker.cs +++ b/Source/Engine/Engine/NativeInterop_Invoker.cs @@ -59,8 +59,10 @@ namespace FlaxEngine return (bool)(object)returnValue ? boolTruePtr : boolFalsePtr; else if (typeof(TRet) == typeof(Type)) return returnValue != null ? GCHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As(returnValue))) : IntPtr.Zero; - else if (typeof(TRet) == typeof(object[])) - return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak)) : IntPtr.Zero; + else if (typeof(TRet).IsArray && ArrayFactory.GetMarshalledType(typeof(TRet).GetElementType()) == typeof(TRet).GetElementType()) + return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnValue)), GCHandleType.Weak)) : IntPtr.Zero; + else if (typeof(TRet).IsArray) + return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak)) : IntPtr.Zero; else return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(returnValue, GCHandleType.Weak)) : IntPtr.Zero; } diff --git a/Source/Engine/Renderer/Renderer.cs b/Source/Engine/Renderer/Renderer.cs index b0dcf9b30..b3def6d50 100644 --- a/Source/Engine/Renderer/Renderer.cs +++ b/Source/Engine/Renderer/Renderer.cs @@ -20,7 +20,7 @@ namespace FlaxEngine return; var temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME var tempCount = temp.Length; - Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), ref temp, ref tempCount); + Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), temp, ref tempCount); } } } diff --git a/Source/Engine/Scripting/DotNet/CoreCLR.cpp b/Source/Engine/Scripting/DotNet/CoreCLR.cpp index 5026dc805..9235443cb 100644 --- a/Source/Engine/Scripting/DotNet/CoreCLR.cpp +++ b/Source/Engine/Scripting/DotNet/CoreCLR.cpp @@ -129,26 +129,10 @@ void CoreCLR::RegisterNativeLibrary(const char* moduleName, const char* modulePa void* CoreCLR::Allocate(int size) { -#if PLATFORM_WINDOWS - void* ptr = CoTaskMemAlloc(size); -#else - void* ptr = malloc(size); -#endif - -#if COMPILE_WITH_PROFILER - Platform::OnMemoryAlloc(ptr, size); -#endif - return ptr; + return Platform::Allocate(size, 16); } void CoreCLR::Free(void* ptr) { -#if COMPILE_WITH_PROFILER - Platform::OnMemoryFree(ptr); -#endif -#if PLATFORM_WINDOWS - CoTaskMemFree(ptr); -#else - free(ptr); -#endif + Platform::Free(ptr); } diff --git a/Source/Engine/Scripting/DotNet/MonoApi.cpp b/Source/Engine/Scripting/DotNet/MonoApi.cpp index 39458f26e..c6a365a2e 100644 --- a/Source/Engine/Scripting/DotNet/MonoApi.cpp +++ b/Source/Engine/Scripting/DotNet/MonoApi.cpp @@ -93,11 +93,11 @@ public: CoreCLR::CallStaticMethod(GetManagedClassesPtr, _assemblyHandle, &managedClasses, &classCount); for (int i = 0; i < classCount; i++) { - CoreCLRClass* mci = New(managedClasses[i].typeHandle, StringAnsi(managedClasses[i].name), StringAnsi(managedClasses[i].fullname), StringAnsi(managedClasses[i].namespace_), managedClasses[i].typeAttributes, this); - _classes.Add(mci); + CoreCLRClass* klass = New(managedClasses[i].typeHandle, StringAnsi(managedClasses[i].name), StringAnsi(managedClasses[i].fullname), StringAnsi(managedClasses[i].namespace_), managedClasses[i].typeAttributes, this); + _classes.Add(klass); ASSERT(managedClasses[i].typeHandle != nullptr); - classHandles.Add(managedClasses[i].typeHandle, mci); + classHandles.Add(managedClasses[i].typeHandle, klass); CoreCLR::Free((void*)managedClasses[i].name); CoreCLR::Free((void*)managedClasses[i].fullname); @@ -168,6 +168,8 @@ public: : _typeHandle(typeHandle), _name(name), _fullname(fullname), _namespace(namespace_), _typeAttributes(typeAttributes), _image(image) { _typeToken = TypeTokenPool++; + _monoType = 0; + _size = 0; } ~CoreCLRClass() @@ -368,6 +370,7 @@ public: CoreCLRMethod(StringAnsi name, int numParams, void* methodHandle, uint32 flags, CoreCLRClass* klass) :_name(name), _numParams(numParams), _methodHandle(methodHandle), _methodAttributes(flags), _class(klass) { + _returnType = nullptr; } const StringAnsi& GetName() const @@ -481,8 +484,12 @@ public: { if (getter != nullptr) _getMethod = New(StringAnsi(_name + "Get"), 1, getter, getterFlags, klass); + else + _getMethod = nullptr; if (setter != nullptr) _setMethod = New(StringAnsi(_name + "Set"), 1, setter, setterFlags, klass); + else + _setMethod = nullptr; } const StringAnsi& GetName() const @@ -617,12 +624,12 @@ void* CoreCLR::GetCustomAttribute(void* klass, void* attribClass) } Array CoreCLR::GetCustomAttributes(void* klass) { - Array attrib = ((CoreCLRClass*)klass)->GetCustomAttributes(); + Array attribs = ((CoreCLRClass*)klass)->GetCustomAttributes(); Array attributes; - attributes.Resize(attrib.Count(), false); - for (int i = 0; i < attrib.Count(); i++) - attributes.Add(attrib[i]->GetHandle()); + attributes.Resize(attribs.Count(), false); + for (int i = 0; i < attribs.Count(); i++) + attributes.Add(attribs[i]->GetHandle()); return attributes; } @@ -754,8 +761,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_value_box(MonoDomain* domain, Mo MONO_API void mono_value_copy(void* dest, /*const*/ void* src, MonoClass* klass) { - CoreCLRClass* mci = (CoreCLRClass*)klass; - Platform::MemoryCopy(dest, src, mci->GetSize()); + Platform::MemoryCopy(dest, src, ((CoreCLRClass*)klass)->GetSize()); } MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_object_get_class(MonoObject* obj) @@ -763,10 +769,9 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_object_get_class(MonoObject* obj) static void* GetObjectTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetObjectType")); void* classHandle = CoreCLR::CallStaticMethod(GetObjectTypePtr, obj); - CoreCLRClass* mi = GetOrCreateClass((void*)classHandle); - - ASSERT(mi != nullptr) - return (MonoClass*)mi; + CoreCLRClass* klass = GetOrCreateClass((void*)classHandle); + ASSERT(klass != nullptr) + return (MonoClass*)klass; } MONO_API void* mono_object_unbox(MonoObject* obj) @@ -794,25 +799,17 @@ MONO_API MonoMethod* mono_object_get_virtual_method(MonoObject* obj, MonoMethod* MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_runtime_invoke(MonoMethod* method, void* obj, void** params, MonoObject** exc) { - CoreCLRMethod* mi = (CoreCLRMethod*)method; - void* methodPtr = mi->GetMethodHandle(); - ASSERT(methodPtr != nullptr); - static void* InvokeMethodPtr = CoreCLR::GetStaticMethodPointer(TEXT("InvokeMethod")); MonoObject* execTmp = nullptr; if (!exc) exc = &execTmp; - return (MonoObject*)CoreCLR::CallStaticMethod(InvokeMethodPtr, obj, methodPtr, params, exc); + return (MonoObject*)CoreCLR::CallStaticMethod(InvokeMethodPtr, obj, ((CoreCLRMethod*)method)->GetMethodHandle(), params, exc); } MONO_API MONO_RT_EXTERNAL_ONLY void* mono_method_get_unmanaged_thunk(MonoMethod* method) { - CoreCLRMethod* mi = (CoreCLRMethod*)method; - void* methodPtr = mi->GetMethodHandle(); - ASSERT(methodPtr != nullptr); - static void* GetMethodUnmanagedFunctionPointerPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodUnmanagedFunctionPointer")); - return CoreCLR::CallStaticMethod(GetMethodUnmanagedFunctionPointerPtr, methodPtr); + return CoreCLR::CallStaticMethod(GetMethodUnmanagedFunctionPointerPtr, ((CoreCLRMethod*)method)->GetMethodHandle()); } MONO_API void mono_field_set_value(MonoObject* obj, MonoClassField* field, void* value) @@ -1108,8 +1105,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_method MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_class(MonoClass* klass) { - CoreCLRClass* mi = (CoreCLRClass*)klass; - MonoCustomAttrInfo* info = (MonoCustomAttrInfo*)New>(mi->GetCustomAttributes()); + MonoCustomAttrInfo* info = (MonoCustomAttrInfo*)New>(((CoreCLRClass*)klass)->GetCustomAttributes()); return info; } @@ -1154,8 +1150,8 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_custom_attrs_get_attr(MonoCustom MONO_API void mono_custom_attrs_free(MonoCustomAttrInfo* ainfo) { - Array* mcai = (Array*)ainfo; - Delete(mcai); + Array* attribs = (Array*)ainfo; + Delete(attribs); } MONO_API MONO_RT_EXTERNAL_ONLY MonoType* mono_reflection_type_get_type(MonoReflectionType* reftype) @@ -1179,8 +1175,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_class_from_name(MonoImage* image, StringAnsi name_space(name_space_); StringAnsi name(name_); - CoreCLRAssembly* mi = (CoreCLRAssembly*)image; - for (auto klass : mi->GetClasses()) + for (auto klass : ((CoreCLRAssembly*)image)->GetClasses()) { if (klass->GetNamespace() == name_space && klass->GetName() == name) return (MonoClass*)klass; @@ -1201,8 +1196,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_array_class_get(MonoClass* elemen MONO_API MONO_RT_EXTERNAL_ONLY MonoClassField* mono_class_get_field_from_name(MonoClass* klass, const char* name) { - CoreCLRClass* mi = (CoreCLRClass*)klass; - for (auto field : mi->GetFields()) + for (auto field : ((CoreCLRClass*)klass)->GetFields()) { if (field->GetName() == name) return (MonoClassField*)field; @@ -1212,8 +1206,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY MonoClassField* mono_class_get_field_from_name(Mo MONO_API MonoProperty* mono_class_get_property_from_name(MonoClass* klass, const char* name) { - CoreCLRClass* mi = (CoreCLRClass*)klass; - for (auto prop : mi->GetProperties()) + for (auto prop : ((CoreCLRClass*)klass)->GetProperties()) { if (prop->GetName() == name) return (MonoProperty*)prop; @@ -1246,8 +1239,8 @@ MONO_API mono_bool mono_class_is_subclass_of(MonoClass* klass, MonoClass* klassc MONO_API char* mono_type_get_name(MonoType* type) { - CoreCLRClass* mci = (CoreCLRClass*)mono_type_get_class(type); - return StringAnsi(mci->GetFullname()).Get(); + CoreCLRClass* klass = (CoreCLRClass*)mono_type_get_class(type); + return StringAnsi(klass->GetFullname()).Get(); } MONO_API MonoImage* mono_class_get_image(MonoClass* klass) @@ -1495,8 +1488,7 @@ MONO_API mono_bool mono_type_is_reference(MonoType* type) MONO_API MonoType* mono_signature_get_return_type(MonoMethodSignature* sig) { - CoreCLRMethod* mi = (CoreCLRMethod*)sig; - return (MonoType*)mi->GetReturnType(); + return (MonoType*)((CoreCLRMethod*)sig)->GetReturnType(); } MONO_API MonoType* mono_signature_get_params(MonoMethodSignature* sig, void** iter) @@ -1514,15 +1506,13 @@ MONO_API MonoType* mono_signature_get_params(MonoMethodSignature* sig, void** it MONO_API uint32 mono_signature_get_param_count(MonoMethodSignature* sig) { - CoreCLRMethod* mi = (CoreCLRMethod*)sig; - return mi->GetNumParameters(); + return ((CoreCLRMethod*)sig)->GetNumParameters(); } MONO_API mono_bool mono_signature_param_is_out(MonoMethodSignature* sig, int param_num) { - CoreCLRMethod* mi = (CoreCLRMethod*)sig; static void* GetMethodParameterIsOutPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodParameterIsOut")); - return CoreCLR::CallStaticMethod(GetMethodParameterIsOutPtr, mi->GetMethodHandle(), param_num); + return CoreCLR::CallStaticMethod(GetMethodParameterIsOutPtr, ((CoreCLRMethod*)sig)->GetMethodHandle(), param_num); } MONO_API int mono_type_stack_size(MonoType* type, int* alignment) diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.h b/Source/Engine/Scripting/ManagedCLR/MUtils.h index 01a6235ca..a100cce9f 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.h +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.h @@ -615,7 +615,6 @@ namespace MUtils FORCE_INLINE bool* ToBoolArray(const BitArray<>& data) { bool* arr = (bool*)CoreCLR::Allocate(data.Count() * sizeof(bool)); - //memcpy(arr, data.Get(), data.Count() * sizeof(bool)); for (int i = 0; i < data.Count(); i++) arr[i] = data[i]; return arr; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Api.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Api.cs index d42f662a9..93588f3bb 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Api.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Api.cs @@ -172,11 +172,7 @@ namespace Flax.Build.Bindings // Skip for collections if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "Dictionary" || typeInfo.Type == "HashSet") && typeInfo.GenericArgs != null) -#if !USE_NETCORE return false; -#else - return true; -#endif // Skip for special types if (typeInfo.GenericArgs == null) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 2ae2e509d..c2179ba97 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -478,6 +478,7 @@ namespace Flax.Build.Bindings } #if USE_NETCORE + var returnNativeType = GenerateCSharpManagedToNativeType(buildData, functionInfo.ReturnType, caller); string returnMarshalType = ""; if (returnValueType == "bool") returnMarshalType = "MarshalAs(UnmanagedType.U1)"; @@ -492,6 +493,12 @@ namespace Flax.Build.Bindings // Interfaces are not supported by NativeMarshallingAttribute, marshal the parameter returnMarshalType = $"MarshalUsing(typeof({returnValueType}Marshaller))"; } + else if (functionInfo.ReturnType.Type == "MonoArray") + returnMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))"; + else if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer" || functionInfo.ReturnType.Type == "BytesContainer" || returnNativeType == "Array") + returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = nameof(__returnCount))"; + else if (functionInfo.ReturnType.Type == "Dictionary") + returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.DictionaryMarshaller<,>), ConstantElementCount = 0)"; else if (returnValueType == "byte[]") returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"__returnCount\")"; else if (returnValueType == "bool[]") @@ -576,7 +583,7 @@ namespace Flax.Build.Bindings string parameterMarshalType = ""; if (parameterInfo.IsOut && parameterInfo.DefaultValue == "var __resultAsRef") { - if (functionInfo.Glue.UseResultReferenceCount) + if (parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BytesContainer") parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")"; else if (parameterInfo.Type.Type == "Dictionary") parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.DictionaryMarshaller<,>), ConstantElementCount = 0)"; @@ -819,7 +826,6 @@ namespace Flax.Build.Bindings { marshallerName = classInfo.Name + "Marshaller"; contents.Append(indent).AppendLine($"[NativeMarshalling(typeof({marshallerName}))]"); - //contents.Append(indent).AppendLine($"[NativeMarshalling(typeof(FlaxEngine.GCHandleMarshaller2<{classInfo.Name}>.GCHandleMarshaller3<{classInfo.Name}>))]"); } #endif contents.Append(indent); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 6c8db23f9..bc49c284f 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -879,6 +879,7 @@ namespace Flax.Build.Bindings CustomParameters = new List(), }; + bool returnTypeIsContainer = false; var returnValueConvert = GenerateCppWrapperNativeToManaged(buildData, functionInfo.ReturnType, caller, out var returnValueType, functionInfo); if (functionInfo.Glue.UseReferenceForResult) { @@ -894,26 +895,11 @@ namespace Flax.Build.Bindings }, IsOut = true, }); -#if USE_NETCORE - if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer") - { - functionInfo.Glue.UseResultReferenceCount = true; - functionInfo.Glue.CustomParameters.Add(new FunctionInfo.ParameterInfo - { - Name = "__resultAsRefCount", - DefaultValue = "var __resultAsRefCount", - Type = new TypeInfo - { - Type = "int" - }, - IsOut = true, - }); - } -#endif } #if USE_NETCORE - else if (functionInfo.ReturnType.Type == "BitArray" || functionInfo.ReturnType.Type == "BytesContainer") + else if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer" || functionInfo.ReturnType.Type == "BitArray" || functionInfo.ReturnType.Type == "BytesContainer") { + returnTypeIsContainer = true; functionInfo.Glue.CustomParameters.Add(new FunctionInfo.ParameterInfo { Name = "__returnCount", @@ -1048,22 +1034,14 @@ namespace Flax.Build.Bindings } #if USE_NETCORE - string callBegin2 = ""; - if (functionInfo.Glue.UseResultReferenceCount) + string callReturnCount = ""; + if (returnTypeIsContainer) { - callBegin2 = " "; + callReturnCount = " "; if (functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "BytesContainer") - callBegin2 += "*__resultAsRefCount = {0}.Length();"; + callReturnCount += "*__returnCount = {0}.Length();"; else - callBegin2 += "*__resultAsRefCount = {0}.Count();"; - } - else if (functionInfo.ReturnType.Type == "BitArray" || functionInfo.ReturnType.Type == "BytesContainer") - { - callBegin2 = " "; - if (functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "BytesContainer") - callBegin2 += "*__returnCount = {0}.Length();"; - else - callBegin2 += "*__returnCount = {0}.Count();"; + callReturnCount += "*__returnCount = {0}.Count();"; } #endif string call; @@ -1102,16 +1080,6 @@ namespace Flax.Build.Bindings } else { -#if USE_NETCORE - // FIXME - if (parameterInfo.Type.Type == "Span" || - parameterInfo.Type.Type == "Array" || - parameterInfo.Type.Type == "DataContainer" || - parameterInfo.Type.Type == "Dictionary") - { - name = '*' + name; - } -#endif // Convert value param += string.Format(CppParamsWrappersCache[i], name); } @@ -1155,11 +1123,11 @@ namespace Flax.Build.Bindings } #if USE_NETCORE - if (!string.IsNullOrEmpty(callBegin2)) + if (!string.IsNullOrEmpty(callReturnCount)) { contents.Append(" ").Append("const auto& callTemp = ").Append(string.Format(callFormat, call, callParams)).Append(";").AppendLine(); call = "callTemp"; - contents.Append(string.Format(callBegin2, call)); + contents.Append(string.Format(callReturnCount, call)); contents.AppendLine(); contents.Append(callBegin); } diff --git a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs index 5cbc809a4..e301053ac 100644 --- a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs @@ -60,7 +60,6 @@ namespace Flax.Build.Bindings public struct GlueInfo { public bool UseReferenceForResult; - public bool UseResultReferenceCount; public List CustomParameters; }