diff --git a/Source/Editor/Scripting/ScriptsBuilder.cpp b/Source/Editor/Scripting/ScriptsBuilder.cpp index 84df897e6..ea58f3240 100644 --- a/Source/Editor/Scripting/ScriptsBuilder.cpp +++ b/Source/Editor/Scripting/ScriptsBuilder.cpp @@ -78,7 +78,7 @@ namespace ScriptsBuilderImpl void onScriptsReloadEnd(); void onScriptsLoaded(); - void GetClassName(const StringAnsi& fullname, StringAnsi& className); + void GetClassName(const StringAnsiView fullname, StringAnsi& className); void onCodeEditorAsyncOpenBegin() { @@ -273,7 +273,7 @@ bool ScriptsBuilder::GenerateProject(const StringView& customArgs) return RunBuildTool(args); } -void ScriptsBuilderImpl::GetClassName(const StringAnsi& fullname, StringAnsi& className) +void ScriptsBuilderImpl::GetClassName(const StringAnsiView fullname, StringAnsi& className) { const auto lastDotIndex = fullname.FindLast('.'); if (lastDotIndex != -1) diff --git a/Source/Engine/Core/Memory/ArenaAllocation.h b/Source/Engine/Core/Memory/ArenaAllocation.h index 18915853d..43004ab30 100644 --- a/Source/Engine/Core/Memory/ArenaAllocation.h +++ b/Source/Engine/Core/Memory/ArenaAllocation.h @@ -44,9 +44,19 @@ public: return ptr; } + // Invokes destructor on values in an array and clears it. + template + static void ClearDelete(Array& collection) + { + Value* ptr = collection.Get(); + for (int32 i = 0; i < collection.Count(); i++) + Memory::DestructItem(ptr[i]); + collection.Clear(); + } + // Invokes destructor on values in a dictionary and clears it. template - void ClearDelete(Dictionary& collection) + static void ClearDelete(Dictionary& collection) { for (auto it = collection.Begin(); it.IsNotEnd(); ++it) Memory::DestructItem(it->Value); diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index f45856443..873aba0eb 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -118,7 +118,7 @@ VariantType::VariantType(Types type, const MClass* klass) #if USE_CSHARP if (klass) { - const StringAnsi& typeName = klass->GetFullName(); + const StringAnsiView typeName = klass->GetFullName(); const int32 length = typeName.Length(); TypeName = static_cast(Allocator::Allocate(length + 1)); Platform::MemoryCopy(TypeName, typeName.Get(), length); diff --git a/Source/Engine/Debug/DebugCommands.cpp b/Source/Engine/Debug/DebugCommands.cpp index fcea938aa..6927a1da9 100644 --- a/Source/Engine/Debug/DebugCommands.cpp +++ b/Source/Engine/Debug/DebugCommands.cpp @@ -215,7 +215,7 @@ namespace { if (!method->IsStatic()) continue; - const StringAnsi& name = method->GetName(); + const StringAnsiView name = method->GetName(); if (name.Contains("Internal_") || mclass->GetFullName().Contains(".Interop.")) continue; diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 3030b041d..1a48a3846 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -1029,7 +1029,7 @@ void ManagedBinaryModule::InitType(MClass* mclass) { #if !COMPILE_WITHOUT_CSHARP // Skip if already initialized - const StringAnsi& typeName = mclass->GetFullName(); + const StringAnsiView typeName = mclass->GetFullName(); if (TypeNameToTypeIndex.ContainsKey(typeName)) return; PROFILE_MEM(Scripting); diff --git a/Source/Engine/Scripting/ManagedCLR/MAssembly.h b/Source/Engine/Scripting/ManagedCLR/MAssembly.h index 2e5af191a..6c0aa9579 100644 --- a/Source/Engine/Scripting/ManagedCLR/MAssembly.h +++ b/Source/Engine/Scripting/ManagedCLR/MAssembly.h @@ -7,6 +7,7 @@ #include "Engine/Core/Types/String.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Collections/Dictionary.h" +#include "Engine/Core/Memory/ArenaAllocation.h" #include "Engine/Platform/CriticalSection.h" /// @@ -19,7 +20,7 @@ class FLAXENGINE_API MAssembly friend Scripting; public: - typedef Dictionary ClassesDictionary; + typedef Dictionary ClassesDictionary; private: #if USE_MONO @@ -67,6 +68,15 @@ public: /// ~MAssembly(); +public: + /// + /// Memory storage with all assembly-related data that shares its lifetime (eg. metadata). + /// + ArenaAllocator Memory; + + // Allocates the given string within a memory that has lifetime of assembly. + StringAnsiView AllocString(const char* str); + public: /// /// Managed assembly actions delegate type. diff --git a/Source/Engine/Scripting/ManagedCLR/MClass.h b/Source/Engine/Scripting/ManagedCLR/MClass.h index b44c446cb..a74b4f7da 100644 --- a/Source/Engine/Scripting/ManagedCLR/MClass.h +++ b/Source/Engine/Scripting/ManagedCLR/MClass.h @@ -17,14 +17,13 @@ private: mutable void* _attrInfo = nullptr; #elif USE_NETCORE void* _handle; - StringAnsi _name; - StringAnsi _namespace; + StringAnsiView _name; + StringAnsiView _namespace; + StringAnsiView _fullname; uint32 _types = 0; mutable uint32 _size = 0; #endif - const MAssembly* _assembly; - - StringAnsi _fullname; + MAssembly* _assembly; mutable Array _methods; mutable Array _fields; @@ -47,12 +46,13 @@ private: int32 _isInterface : 1; int32 _isValueType : 1; int32 _isEnum : 1; + int32 _isGeneric : 1; public: #if USE_MONO MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const StringAnsi& fullname); #elif USE_NETCORE - MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes typeAttributes); + MClass(MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes typeAttributes); #endif /// @@ -64,7 +64,7 @@ public: /// /// Gets the parent assembly. /// - const MAssembly* GetAssembly() const + FORCE_INLINE MAssembly* GetAssembly() const { return _assembly; } @@ -72,7 +72,7 @@ public: /// /// Gets the full name of the class (namespace and typename). /// - FORCE_INLINE const StringAnsi& GetFullName() const + FORCE_INLINE StringAnsiView GetFullName() const { return _fullname; } @@ -80,12 +80,18 @@ public: /// /// Gets the name of the class. /// - StringAnsiView GetName() const; + FORCE_INLINE StringAnsiView GetName() const + { + return _name; + } /// /// Gets the namespace of the class. /// - StringAnsiView GetNamespace() const; + FORCE_INLINE StringAnsiView GetNamespace() const + { + return _name; + } #if USE_MONO /// @@ -161,9 +167,9 @@ public: /// /// Gets if class is generic /// - bool IsGeneric() const + FORCE_INLINE bool IsGeneric() const { - return _fullname.FindLast('`') != -1; + return _isGeneric != 0; } /// diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.cpp b/Source/Engine/Scripting/ManagedCLR/MCore.cpp index 8761c309c..4ded56b52 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MCore.cpp @@ -71,6 +71,17 @@ MAssembly::~MAssembly() Unload(); } +StringAnsiView MAssembly::AllocString(const char* str) +{ + if (!str) + return StringAnsiView::Empty; + int32 len = StringUtils::Length(str); + char* mem = (char*)Memory.Allocate(len + 1); + Platform::MemoryCopy(mem, str, len); + mem[len] = 0; + return StringAnsiView(mem, len); +} + String MAssembly::ToString() const { return _name.ToString(); @@ -127,7 +138,11 @@ void MAssembly::Unload(bool isReloading) _isLoading = false; _isLoaded = false; _hasCachedClasses = false; +#if USE_NETCORE + ArenaAllocator::ClearDelete(_classes); +#else _classes.ClearDelete(); +#endif Unloaded(this); } diff --git a/Source/Engine/Scripting/ManagedCLR/MEvent.h b/Source/Engine/Scripting/ManagedCLR/MEvent.h index 52573e204..0aade183e 100644 --- a/Source/Engine/Scripting/ManagedCLR/MEvent.h +++ b/Source/Engine/Scripting/ManagedCLR/MEvent.h @@ -15,16 +15,16 @@ class FLAXENGINE_API MEvent protected: #if USE_MONO MonoEvent* _monoEvent; + StringAnsi _name; #elif USE_NETCORE void* _handle; + StringAnsiView _name; #endif mutable MMethod* _addMethod; mutable MMethod* _removeMethod; MClass* _parentClass; - StringAnsi _name; - mutable int32 _hasCachedAttributes : 1; mutable int32 _hasAddMonoMethod : 1; mutable int32 _hasRemoveMonoMethod : 1; @@ -42,7 +42,7 @@ public: /// /// Gets the event name. /// - FORCE_INLINE const StringAnsi& GetName() const + FORCE_INLINE StringAnsiView GetName() const { return _name; } diff --git a/Source/Engine/Scripting/ManagedCLR/MField.h b/Source/Engine/Scripting/ManagedCLR/MField.h index 49bce9f54..ed73db711 100644 --- a/Source/Engine/Scripting/ManagedCLR/MField.h +++ b/Source/Engine/Scripting/ManagedCLR/MField.h @@ -17,14 +17,15 @@ protected: #if USE_MONO MonoClassField* _monoField; MonoType* _monoType; + StringAnsi _name; #elif USE_NETCORE void* _handle; void* _type; int32 _fieldOffset; + StringAnsiView _name; #endif MClass* _parentClass; - StringAnsi _name; MVisibility _visibility; @@ -44,7 +45,7 @@ public: /// /// Gets field name. /// - FORCE_INLINE const StringAnsi& GetName() const + FORCE_INLINE StringAnsiView GetName() const { return _name; } diff --git a/Source/Engine/Scripting/ManagedCLR/MMethod.h b/Source/Engine/Scripting/ManagedCLR/MMethod.h index 989147754..8d24b533b 100644 --- a/Source/Engine/Scripting/ManagedCLR/MMethod.h +++ b/Source/Engine/Scripting/ManagedCLR/MMethod.h @@ -21,15 +21,16 @@ class FLAXENGINE_API MMethod protected: #if USE_MONO MonoMethod* _monoMethod; + StringAnsi _name; #elif USE_NETCORE void* _handle; + StringAnsiView _name; int32 _paramsCount; mutable void* _returnType; mutable Array> _parameterTypes; void CacheSignature() const; #endif MClass* _parentClass; - StringAnsi _name; MVisibility _visibility; #if !USE_MONO_AOT void* _cachedThunk = nullptr; @@ -48,12 +49,11 @@ public: explicit MMethod(MonoMethod* monoMethod, MClass* parentClass); explicit MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass); #elif USE_NETCORE - MMethod(MClass* parentClass, StringAnsi&& name, void* handle, int32 paramsCount, MMethodAttributes attributes); + MMethod(MClass* parentClass, StringAnsiView name, void* handle, int32 paramsCount, MMethodAttributes attributes); #endif public: #if COMPILE_WITH_PROFILER - StringAnsi ProfilerName; SourceLocationData ProfilerData; #endif @@ -109,7 +109,7 @@ public: /// /// Gets the method name. /// - FORCE_INLINE const StringAnsi& GetName() const + FORCE_INLINE StringAnsiView GetName() const { return _name; } diff --git a/Source/Engine/Scripting/ManagedCLR/MProperty.h b/Source/Engine/Scripting/ManagedCLR/MProperty.h index 3be94eb1a..7e426b474 100644 --- a/Source/Engine/Scripting/ManagedCLR/MProperty.h +++ b/Source/Engine/Scripting/ManagedCLR/MProperty.h @@ -17,16 +17,16 @@ class FLAXENGINE_API MProperty protected: #if USE_MONO MonoProperty* _monoProperty; + StringAnsi _name; #elif USE_NETCORE void* _handle; + StringAnsiView _name; #endif mutable MMethod* _getMethod; mutable MMethod* _setMethod; MClass* _parentClass; - StringAnsi _name; - mutable int32 _hasCachedAttributes : 1; mutable int32 _hasSetMethod : 1; mutable int32 _hasGetMethod : 1; @@ -49,7 +49,7 @@ public: /// /// Gets the property name. /// - FORCE_INLINE const StringAnsi& GetName() const + FORCE_INLINE StringAnsiView GetName() const { return _name; } diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp index a52d55f67..fd0596ef5 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp @@ -150,7 +150,7 @@ ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MTypeObject* value) MClass* klass = GetClass(value); if (!klass) return ScriptingTypeHandle(); - const StringAnsi& typeName = klass->GetFullName(); + const StringAnsiView typeName = klass->GetFullName(); const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeName); if (!typeHandle) LOG(Warning, "Unknown scripting type {}", String(typeName)); @@ -821,14 +821,14 @@ MObject* MUtils::BoxVariant(const Variant& value) } } -const StringAnsi& MUtils::GetClassFullname(MObject* obj) +StringAnsiView MUtils::GetClassFullname(MObject* obj) { if (obj) { MClass* mClass = MCore::Object::GetClass(obj); return mClass->GetFullName(); } - return StringAnsi::Empty; + return StringAnsiView::Empty; } MClass* MUtils::GetClass(MTypeObject* type) diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.h b/Source/Engine/Scripting/ManagedCLR/MUtils.h index f3bc27172..f642681d2 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.h +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.h @@ -400,7 +400,7 @@ struct MConverter> namespace MUtils { // Outputs the full typename for the type of the specified object. - extern FLAXENGINE_API const StringAnsi& GetClassFullname(MObject* obj); + extern FLAXENGINE_API StringAnsiView GetClassFullname(MObject* obj); // Returns the class of the provided object. extern FLAXENGINE_API MClass* GetClass(MObject* object); diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index d56c0e5ea..cd4da3f20 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -183,7 +183,7 @@ Dictionary CachedAssemblyHandles; /// /// Returns the function pointer to the managed static method in NativeInterop class. /// -void* GetStaticMethodPointer(const String& methodName); +void* GetStaticMethodPointer(StringView methodName); /// /// Calls the managed static method with given parameters. @@ -753,12 +753,13 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const static void* GetManagedClassesPtr = GetStaticMethodPointer(TEXT("GetManagedClasses")); CallStaticMethod(GetManagedClassesPtr, _handle, &managedClasses, &classCount); _classes.EnsureCapacity(classCount); + MAssembly* assembly = const_cast(this); for (int32 i = 0; i < classCount; i++) { NativeClassDefinitions& managedClass = managedClasses[i]; // Create class object - MClass* klass = New(this, managedClass.typeHandle, managedClass.name, managedClass.fullname, managedClass.namespace_, managedClass.typeAttributes); + MClass* klass = assembly->Memory.New(assembly, managedClass.typeHandle, managedClass.name, managedClass.fullname, managedClass.namespace_, managedClass.typeAttributes); _classes.Add(klass->GetFullName(), klass); managedClass.nativePointer = klass; @@ -811,7 +812,7 @@ DEFINE_INTERNAL_CALL(void) NativeInterop_CreateClass(NativeClassDefinitions* man CachedAssemblyHandles.Add(assemblyHandle, assembly); } - MClass* klass = New(assembly, managedClass->typeHandle, managedClass->name, managedClass->fullname, managedClass->namespace_, managedClass->typeAttributes); + MClass* klass = assembly->Memory.New(assembly, managedClass->typeHandle, managedClass->name, managedClass->fullname, managedClass->namespace_, managedClass->typeAttributes); if (assembly != nullptr) { auto& classes = const_cast(assembly->GetClasses()); @@ -819,7 +820,7 @@ DEFINE_INTERNAL_CALL(void) NativeInterop_CreateClass(NativeClassDefinitions* man if (classes.TryGet(klass->GetFullName(), oldKlass)) { LOG(Warning, "Class '{0}' was already added to assembly '{1}'", String(klass->GetFullName()), String(assembly->GetName())); - Delete(klass); + Memory::DestructItem(klass); klass = oldKlass; } else @@ -915,12 +916,12 @@ bool MAssembly::UnloadImage(bool isReloading) return false; } -MClass::MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes attributes) +MClass::MClass(MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes attributes) : _handle(handle) - , _name(name) - , _namespace(namespace_) + , _name(parentAssembly->AllocString(name)) + , _namespace(parentAssembly->AllocString(namespace_)) + , _fullname(parentAssembly->AllocString(fullname)) , _assembly(parentAssembly) - , _fullname(fullname) , _hasCachedProperties(false) , _hasCachedFields(false) , _hasCachedMethods(false) @@ -967,6 +968,8 @@ MClass::MClass(const MAssembly* parentAssembly, void* handle, const char* name, static void* TypeIsEnumPtr = GetStaticMethodPointer(TEXT("TypeIsEnum")); _isEnum = CallStaticMethod(TypeIsEnumPtr, handle); + _isGeneric = _fullname.FindLast('`') != -1; + CachedClassHandles[handle] = this; } @@ -982,24 +985,14 @@ bool MAssembly::ResolveMissingFile(String& assemblyPath) const MClass::~MClass() { - _methods.ClearDelete(); - _fields.ClearDelete(); - _properties.ClearDelete(); - _events.ClearDelete(); + ArenaAllocator::ClearDelete(_methods); + ArenaAllocator::ClearDelete(_fields); + ArenaAllocator::ClearDelete(_properties); + ArenaAllocator::ClearDelete(_events); CachedClassHandles.Remove(_handle); } -StringAnsiView MClass::GetName() const -{ - return _name; -} - -StringAnsiView MClass::GetNamespace() const -{ - return _namespace; -} - MType* MClass::GetType() const { return (MType*)_handle; @@ -1071,10 +1064,11 @@ const Array& MClass::GetMethods() const static void* GetClassMethodsPtr = GetStaticMethodPointer(TEXT("GetClassMethods")); CallStaticMethod(GetClassMethodsPtr, _handle, &methods, &methodsCount); _methods.Resize(methodsCount); + MAssembly* assembly = const_cast(_assembly); for (int32 i = 0; i < methodsCount; i++) { NativeMethodDefinitions& definition = methods[i]; - MMethod* method = New(const_cast(this), StringAnsi(definition.name), definition.handle, definition.numParameters, definition.methodAttributes); + MMethod* method = assembly->Memory.New(const_cast(this), assembly->AllocString(definition.name), definition.handle, definition.numParameters, definition.methodAttributes); _methods[i] = method; MCore::GC::FreeMemory((void*)definition.name); } @@ -1112,7 +1106,7 @@ const Array& MClass::GetFields() const for (int32 i = 0; i < numFields; i++) { NativeFieldDefinitions& definition = fields[i]; - MField* field = New(const_cast(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldOffset, definition.fieldAttributes); + MField* field = _assembly->Memory.New(const_cast(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldOffset, definition.fieldAttributes); _fields[i] = field; MCore::GC::FreeMemory((void*)definition.name); } @@ -1162,7 +1156,7 @@ const Array& MClass::GetProperties() const for (int i = 0; i < numProperties; i++) { const NativePropertyDefinitions& definition = foundProperties[i]; - MProperty* property = New(const_cast(this), definition.name, definition.propertyHandle, definition.getterHandle, definition.setterHandle, definition.getterAttributes, definition.setterAttributes); + MProperty* property = _assembly->Memory.New(const_cast(this), definition.name, definition.propertyHandle, definition.getterHandle, definition.setterHandle, definition.getterAttributes, definition.setterAttributes); _properties[i] = property; MCore::GC::FreeMemory((void*)definition.name); } @@ -1241,7 +1235,7 @@ MEvent::MEvent(MClass* parentClass, void* handle, const char* name) , _addMethod(nullptr) , _removeMethod(nullptr) , _parentClass(parentClass) - , _name(name) + , _name(parentClass->GetAssembly()->AllocString(name)) , _hasCachedAttributes(false) , _hasAddMonoMethod(true) , _hasRemoveMonoMethod(true) @@ -1317,7 +1311,7 @@ MField::MField(MClass* parentClass, void* handle, const char* name, void* type, , _type(type) , _fieldOffset(fieldOffset) , _parentClass(parentClass) - , _name(name) + , _name(parentClass->GetAssembly()->AllocString(name)) , _hasCachedAttributes(false) { switch (attributes & MFieldAttributes::FieldAccessMask) @@ -1409,11 +1403,11 @@ const Array& MField::GetAttributes() const return _attributes; } -MMethod::MMethod(MClass* parentClass, StringAnsi&& name, void* handle, int32 paramsCount, MMethodAttributes attributes) +MMethod::MMethod(MClass* parentClass, StringAnsiView name, void* handle, int32 paramsCount, MMethodAttributes attributes) : _handle(handle) , _paramsCount(paramsCount) , _parentClass(parentClass) - , _name(MoveTemp(name)) + , _name(name) , _hasCachedAttributes(false) , _hasCachedSignature(false) { @@ -1443,13 +1437,15 @@ MMethod::MMethod(MClass* parentClass, StringAnsi&& name, void* handle, int32 par _isStatic = (attributes & MMethodAttributes::Static) == MMethodAttributes::Static; #if COMPILE_WITH_PROFILER - const StringAnsi& className = parentClass->GetFullName(); - ProfilerName.Resize(className.Length() + 2 + _name.Length()); - Platform::MemoryCopy(ProfilerName.Get(), className.Get(), className.Length()); - ProfilerName.Get()[className.Length()] = ':'; - ProfilerName.Get()[className.Length() + 1] = ':'; - Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length()); - ProfilerData.name = ProfilerName.Get(); + // Setup Tracy profiler entry (use assembly memory) + const StringAnsiView className = parentClass->GetFullName(); + char* profilerName = (char*)parentClass->GetAssembly()->Memory.Allocate(className.Length() + _name.Length() + 3); + Platform::MemoryCopy(profilerName, className.Get(), className.Length()); + profilerName[className.Length()] = ':'; + profilerName[className.Length() + 1] = ':'; + Platform::MemoryCopy(profilerName + className.Length() + 2, _name.Get(), _name.Length()); + profilerName[className.Length() + 2 + _name.Length()] = 0; + ProfilerData.name = profilerName; ProfilerData.function = _name.Get(); ProfilerData.file = nullptr; ProfilerData.line = 0; @@ -1573,20 +1569,30 @@ const Array& MMethod::GetAttributes() const return _attributes; } +FORCE_INLINE StringAnsiView GetPropertyMethodName(MProperty* property, StringAnsiView prefix) +{ + StringAnsiView name = property->GetName(); + char* mem = (char*)property->GetParentClass()->GetAssembly()->Memory.Allocate(name.Length() + prefix.Length() + 1); + Platform::MemoryCopy(mem, prefix.Get(), prefix.Length()); + Platform::MemoryCopy(mem + prefix.Length(), name.Get(), name.Length()); + mem[name.Length() + prefix.Length()] = 0; + return StringAnsiView(mem, name.Length() + prefix.Length() + 1); +} + MProperty::MProperty(MClass* parentClass, const char* name, void* handle, void* getterHandle, void* setterHandle, MMethodAttributes getterAttributes, MMethodAttributes setterAttributes) : _parentClass(parentClass) - , _name(name) + , _name(parentClass->GetAssembly()->AllocString(name)) , _handle(handle) , _hasCachedAttributes(false) { _hasGetMethod = getterHandle != nullptr; if (_hasGetMethod) - _getMethod = New(parentClass, StringAnsi("get_" + _name), getterHandle, 0, getterAttributes); + _getMethod = parentClass->GetAssembly()->Memory.New(parentClass, GetPropertyMethodName(this, StringAnsiView("get_", 4)), getterHandle, 0, getterAttributes); else _getMethod = nullptr; _hasSetMethod = setterHandle != nullptr; if (_hasSetMethod) - _setMethod = New(parentClass, StringAnsi("set_" + _name), setterHandle, 1, setterAttributes); + _setMethod = parentClass->GetAssembly()->Memory.New(parentClass, GetPropertyMethodName(this, StringAnsiView("set_", 4)), setterHandle, 1, setterAttributes); else _setMethod = nullptr; } @@ -1594,9 +1600,9 @@ MProperty::MProperty(MClass* parentClass, const char* name, void* handle, void* MProperty::~MProperty() { if (_getMethod) - Delete(_getMethod); + Memory::DestructItem(_getMethod); if (_setMethod) - Delete(_setMethod); + Memory::DestructItem(_setMethod); } MMethod* MProperty::GetGetMethod() const @@ -1683,7 +1689,7 @@ MClass* GetOrCreateClass(MType* typeHandle) static void* GetManagedClassFromTypePtr = GetStaticMethodPointer(TEXT("GetManagedClassFromType")); CallStaticMethod(GetManagedClassFromTypePtr, typeHandle, &classInfo, &assemblyHandle); MAssembly* assembly = GetAssembly(assemblyHandle); - klass = New(assembly, classInfo.typeHandle, classInfo.name, classInfo.fullname, classInfo.namespace_, classInfo.typeAttributes); + klass = assembly->Memory.New(assembly, classInfo.typeHandle, classInfo.name, classInfo.fullname, classInfo.namespace_, classInfo.typeAttributes); if (assembly != nullptr) { auto& classes = const_cast(assembly->GetClasses()); @@ -1889,7 +1895,7 @@ void ShutdownHostfxr() { } -void* GetStaticMethodPointer(const String& methodName) +void* GetStaticMethodPointer(StringView methodName) { void* fun; if (CachedFunctions.TryGet(methodName, fun))