Explorar el Código

console works!

Guo Hui hace 6 años
padre
commit
471386102e

+ 1 - 1
CMakeLists.txt

@@ -22,7 +22,7 @@ set(CMAKE_CXX_STANDARD 17)
 
 if (MSVC)
     add_definitions(/D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS /DNOMINMAX /DUNICODE)
-    add_compile_options(/wd4102 /wd4200 /wd4533)
+    add_compile_options(/Zc:threadSafeInit- /wd4102 /wd4200 /wd4533)
     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
     set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
 else()

+ 1 - 1
src/Native/natsu.array.cpp

@@ -44,7 +44,7 @@ void Array::_s_Copy(gc_obj_ref<Array> sourceArray, int32_t sourceIndex, gc_obj_r
     check_null_obj_ref(sourceArray);
     check_null_obj_ref(destinationArray);
     auto src = sourceArray.cast<RawSzArrayData>();
-    auto dest = sourceArray.cast<RawSzArrayData>();
+    auto dest = destinationArray.cast<RawSzArrayData>();
     auto element_size = sourceArray.header().vtable_->ElementSize;
 
     if ((sourceIndex + length) > (intptr_t)src->Count || (destinationIndex + length) > (intptr_t)dest->Count)

+ 1 - 1
src/Native/natsu.fcall.cpp

@@ -19,7 +19,7 @@ using namespace Chino_Threading;
 gc_obj_ref<Type> Object::GetType(::natsu::gc_obj_ref<Object> _this)
 {
     check_null_obj_ref(_this);
-    pure_call();
+    return _this.header().vtable_->runtime_type();
 }
 
 gc_obj_ref<MulticastDelegate> MulticastDelegate::_s_CreateDelegateLike(gc_obj_ref<MulticastDelegate> delegate, gc_obj_ref<SZArray_1<Delegate>> invocationList)

+ 1 - 1
src/Native/natsu.gc.cpp

@@ -392,7 +392,7 @@ using namespace System_Private_CoreLib::System;
 using namespace Chino_Kernel::Chino::Memory;
 using namespace natsu;
 
-gc_obj_ref<Object> natsu::gc_alloc(const vtable_t &vtable, size_t size)
+gc_obj_ref<Object> natsu::gc_alloc(const clr_vtable &vtable, size_t size)
 {
     auto mem_ptr = reinterpret_cast<uint8_t *>(HeapAlloc(size + sizeof(object_header)));
     if (!mem_ptr)

+ 1 - 13
src/Native/natsu.runtime.h

@@ -125,7 +125,7 @@ auto &vtable(gc_obj_ref<> obj) noexcept
     return *static_cast<const typename T::VTable *>(obj.header().vtable_);
 }
 
-gc_obj_ref<::System_Private_CoreLib::System::Object> gc_alloc(const vtable_t &vtable, size_t size);
+gc_obj_ref<::System_Private_CoreLib::System::Object> gc_alloc(const clr_vtable &vtable, size_t size);
 
 template <class T>
 gc_obj_ref<T> gc_new(size_t size)
@@ -204,18 +204,6 @@ void check_condition(TCond &&condition, TArgs &&... args)
         throw make_exception(make_object<T>(std::forward<TArgs>(args)...));
 }
 
-template <class T>
-struct runtime_type_holder
-{
-    static gc_obj_ref<::System_Private_CoreLib::System::RuntimeType> get()
-    {
-        using namespace ::System_Private_CoreLib::System;
-        static auto type = make_object<RuntimeType>(
-            reinterpret_cast<intptr_t>(&vtable_holder<typename T::VTable>::get()));
-        return type;
-    }
-};
-
 template <class TCall>
 class clr_finally
 {

+ 47 - 20
src/Native/natsu.typedef.h

@@ -32,6 +32,7 @@ namespace System
     struct Exception;
     struct String;
     struct Object;
+    struct RuntimeType;
 
     template <class T>
     struct SZArray_1;
@@ -52,6 +53,7 @@ struct gc_ref;
 template <class T>
 struct gc_ptr;
 
+struct clr_vtable;
 struct clr_exception;
 
 [[noreturn]] void throw_null_ref_exception();
@@ -117,23 +119,6 @@ struct vtable_holder
     }
 };
 
-typedef struct _vtable
-{
-    uint32_t ElementSize;
-
-    constexpr _vtable()
-        : ElementSize(0)
-    {
-    }
-
-    virtual void dummy() const noexcept {}
-
-    template <class TFunc>
-    constexpr void override_vfunc_impl(std::string_view name, TFunc func)
-    {
-    }
-} vtable_t;
-
 enum object_attributes
 {
     OBJ_ATTR_NONE
@@ -148,9 +133,9 @@ struct object_header
 {
     object_attributes attributes_;
     object_sync_header sync_header_;
-    const vtable_t *vtable_;
+    const clr_vtable *vtable_;
 
-    constexpr object_header(object_attributes attributes, const vtable_t *vtable)
+    constexpr object_header(object_attributes attributes, const clr_vtable *vtable)
         : attributes_(attributes), vtable_(vtable)
     {
     }
@@ -608,6 +593,26 @@ struct gc_obj_ref
     }
 };
 
+struct clr_vtable
+{
+    uint32_t ElementSize;
+
+    constexpr clr_vtable()
+        : ElementSize(0)
+    {
+    }
+
+    virtual gc_obj_ref<::System_Private_CoreLib::System::RuntimeType> runtime_type() const noexcept
+    {
+        pure_call();
+    }
+
+    template <class TFunc>
+    constexpr void override_vfunc_impl(std::string_view name, TFunc func)
+    {
+    }
+};
+
 struct clr_exception
 {
     template <class T>
@@ -753,7 +758,7 @@ struct vtable_class : public TBase, public vtable_impl_t<TBase, TIFaces>...
     constexpr void override_vfunc(std::string_view name, TFunc func)
     {
         TBase::override_vfunc_impl(name, func);
-        if constexpr (!std::is_same_v<TBase, vtable_t>)
+        if constexpr (!std::is_same_v<TBase, clr_vtable>)
             TBase::override_vfunc(name, func);
         int ignore[] = { 0, (vtable_impl_t<TBase, TIFaces>::override_vfunc_impl(name, func), 0)... };
     }
@@ -789,6 +794,17 @@ struct szarray_literal
     }
 };
 
+template <class T>
+struct runtime_type_literal
+{
+    const void *vtable_;
+
+    constexpr runtime_type_literal()
+        : vtable_(&vtable_holder<typename T::VTable>::get())
+    {
+    }
+};
+
 template <class TObject, class TValue>
 struct static_object
 {
@@ -824,6 +840,17 @@ constexpr auto make_szarray_literal(const std::array<T, N> &values)
     return static_object<::System_Private_CoreLib::System::SZArray_1<T>,
         szarray_literal<T, N>>(values);
 }
+
+template <class T>
+struct runtime_type_holder
+{
+    static const constexpr static_object<::System_Private_CoreLib::System::RuntimeType, runtime_type_literal<T>> value = { runtime_type_literal<T>() };
+
+    static constexpr gc_obj_ref<::System_Private_CoreLib::System::RuntimeType> get() noexcept
+    {
+        return value.get();
+    }
+};
 }
 
 #define NATSU_PRIMITIVE_IMPL_BYTE                     \

+ 37 - 1
src/Natsu.Compiler/Program.cs

@@ -652,7 +652,7 @@ namespace Natsu.Compiler
                 baseSb.Append("::natsu::vtable_class<");
                 var baseType = GetBaseType(type.TypeDef);
                 if (baseType == null)
-                    baseSb.Append("natsu::vtable_t");
+                    baseSb.Append("natsu::clr_vtable");
                 else
                     baseSb.Append($"typename {TypeUtils.EscapeTypeName(baseType, cppBasicType: true)}::VTable");
 
@@ -833,6 +833,12 @@ namespace Natsu.Compiler
 
         private void WriteTypeMethodBody(TextWriter writer, int ident, TypeDesc type, bool inHeader)
         {
+            if (!type.TypeDef.IsAbstract && !type.TypeDef.IsInterface)
+            {
+                if (inHeader == type.TypeDef.HasGenericParameters)
+                    WriteVTableRuntimeTypeMethodBody(writer, ident, type);
+            }
+
             foreach (var method in type.TypeDef.Methods)
             {
                 if (inHeader == (type.TypeDef.HasGenericParameters || method.HasGenericParameters))
@@ -979,6 +985,12 @@ namespace Natsu.Compiler
             }
 
             writer.Ident(ident).WriteLine("}");
+
+            if (!type.TypeDef.IsAbstract && !type.TypeDef.IsInterface)
+            {
+                writer.Ident(ident).WriteLine();
+                writer.Ident(ident).WriteLine("::natsu::gc_obj_ref<::System_Private_CoreLib::System::RuntimeType> runtime_type() const noexcept override;");
+            }
         }
 
         private void WriteVTableMethodDeclare(TextWriter writer, int ident, MethodDef method)
@@ -1024,6 +1036,30 @@ namespace Natsu.Compiler
             writer.Flush();
         }
 
+        private void WriteVTableRuntimeTypeMethodBody(TextWriter writer, int ident, TypeDesc type)
+        {
+            writer.Ident(ident);
+            var typeGens = new List<string>();
+
+            if (type.TypeDef.HasGenericParameters)
+                typeGens.AddRange(type.TypeDef.GenericParameters.Select(x => x.Name.String));
+
+            if (typeGens.Any())
+                writer.WriteLine($"template <{string.Join(", ", typeGens.Select(x => "class " + x))}>");
+
+            writer.Write("::natsu::gc_obj_ref<::System_Private_CoreLib::System::RuntimeType> ");
+            writer.Write(TypeUtils.EscapeTypeName(type.TypeDef, hasModuleName: false));
+            writer.WriteLine("::VTable::runtime_type() const noexcept");
+            writer.Ident(ident).WriteLine("{");
+            writer.Ident(ident + 1).Write($"return ::natsu::runtime_type_holder<");
+            writer.Write(TypeUtils.EscapeTypeName(type.TypeDef, hasModuleName: false));
+            writer.WriteLine(">::get();");
+            writer.Ident(ident).WriteLine("}");
+            writer.WriteLine();
+
+            writer.Flush();
+        }
+
         private void WriteVTableMethodBody(TextWriter writer, int ident, MethodDef method)
         {
             writer.Ident(ident);

+ 1 - 1
src/System.Private.CoreLib/System/RuntimeType.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 
 namespace System
 {
-    internal class RuntimeType : Type
+    internal sealed class RuntimeType : Type
     {
         private readonly IntPtr _eeClass;
 

+ 4 - 4
src/apps/Chino.Apps.Shell/Program.cs

@@ -8,16 +8,16 @@ namespace Chino.Apps.Shell
     {
         static void Main(string[] args)
         {
-            Debug.WriteLine("Hello Shell!");
+            Console.ForegroundColor = ConsoleColor.Green;
+            Console.WriteLine("Hello Shell!");
+            Console.ForegroundColor = ConsoleColor.White;
 
             int i = 0;
             while (true)
             {
                 Thread.Sleep(1000);
-                Debug.WriteLine("Tick" + i++);
+                Console.WriteLine("Tick" + i++);
             }
-
-            //Console.WriteLine("Hello Shell!");
         }
     }
 }