diff --git a/.gitignore b/.gitignore
index 0c34684..fc4ee18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
*.o
*.tmp
-*.bin
\ No newline at end of file
+*.bin
+bin
+obj
+.vs
\ No newline at end of file
diff --git a/Executable.sln b/Executable.sln
new file mode 100644
index 0000000..4694daf
--- /dev/null
+++ b/Executable.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32210.238
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "noruntime", "source\noruntime.csproj", "{BF2D0032-2C24-4527-AE52-54A679B15D9D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BF2D0032-2C24-4527-AE52-54A679B15D9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF2D0032-2C24-4527-AE52-54A679B15D9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF2D0032-2C24-4527-AE52-54A679B15D9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF2D0032-2C24-4527-AE52-54A679B15D9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {56486BA0-B053-49F2-BD72-F1A9E95FD7EE}
+ EndGlobalSection
+EndGlobal
diff --git a/Makefile b/Makefile
deleted file mode 100644
index c23f54f..0000000
--- a/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-SDIR := source
-ODIR := build
-CFILES := $(wildcard $(SDIR)/*.c)
-CLIBFILES := $(wildcard $(SDIR)/lib/*.c)
-CC := gcc
-OBJCOPY := objcopy
-LD = ld
-OBJS := $(patsubst $(SDIR)/%.c, $(ODIR)/%.o, $(CFILES))
-LOBJS := $(patsubst $(SDIR)/lib/%.c, $(ODIR)/%.o, $(CLIBFILES))
-
-CFLAGS = -std=gnu99 -Os -nostdlib -m32 -ffreestanding
-LDFLAGS = -Ttext=0x0 -m elf_i386 --entry main
-
-TARGET = $(shell basename $(CURDIR)).bin
-
-$(TARGET): $(ODIR) $(OBJS) $(LOBJS)
- $(LD) $(ODIR)/*.o $(SDIR)/linker/aura.ld -o $(ODIR)/program.tmp $(LDFLAGS)
- $(OBJCOPY) -O binary $(ODIR)/program.tmp $(ODIR)/program.bin
- rm -f $(ODIR)/program.tmp
-
-$(ODIR)/%.o: $(SDIR)/%.c
- $(CC) -c -o $@ $< $(CFLAGS)
-
-$(ODIR)/%.o: $(SDIR)/lib/%.c
- $(CC) -c -o $@ $< $(CFLAGS)
-
-$(ODIR):
- @mkdir $@
-
-.PHONY: clean
-
-clean:
- rm -f $(TARGET) $(ODIR)/*.o $(ODIR)/program.bin
diff --git a/source/EEType.cs b/source/EEType.cs
new file mode 100644
index 0000000..697c14a
--- /dev/null
+++ b/source/EEType.cs
@@ -0,0 +1,1304 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Internal.Runtime
+{
+ internal enum EETypeElementType
+ {
+ // Primitive
+ Unknown = 0x00,
+ Void = 0x01,
+ Boolean = 0x02,
+ Char = 0x03,
+ SByte = 0x04,
+ Byte = 0x05,
+ Int16 = 0x06,
+ UInt16 = 0x07,
+ Int32 = 0x08,
+ UInt32 = 0x09,
+ Int64 = 0x0A,
+ UInt64 = 0x0B,
+ IntPtr = 0x0C,
+ UIntPtr = 0x0D,
+ Single = 0x0E,
+ Double = 0x0F,
+
+ ValueType = 0x10,
+ // Enum = 0x11, // EETypes store enums as their underlying type
+ Nullable = 0x12,
+ // Unused 0x13,
+
+ Class = 0x14,
+ Interface = 0x15,
+
+ SystemArray = 0x16, // System.Array type
+
+ Array = 0x17,
+ SzArray = 0x18,
+ ByRef = 0x19,
+ Pointer = 0x1A,
+ }
+
+ [Flags]
+ internal enum EETypeFlags : ushort
+ {
+ ///
+ /// There are four kinds of EETypes, defined in Kinds.
+ ///
+ EETypeKindMask = 0x0003,
+
+ ///
+ /// This flag is set when m_RelatedType is in a different module. In that case, _pRelatedType
+ /// actually points to an IAT slot in this module, which then points to the desired EEType in the
+ /// other module. In other words, there is an extra indirection through m_RelatedType to get to
+ /// the related type in the other module. When this flag is set, it is expected that you use the
+ /// "_ppXxxxViaIAT" member of the RelatedTypeUnion for the particular related type you're
+ /// accessing.
+ ///
+ RelatedTypeViaIATFlag = 0x0004,
+
+ ///
+ /// This type was dynamically allocated at runtime.
+ ///
+ IsDynamicTypeFlag = 0x0008,
+
+ ///
+ /// This EEType represents a type which requires finalization.
+ ///
+ HasFinalizerFlag = 0x0010,
+
+ ///
+ /// This type contain GC pointers.
+ ///
+ HasPointersFlag = 0x0020,
+
+ ///
+ /// Type implements ICastable to allow dynamic resolution of interface casts.
+ ///
+ ICastableFlag = 0x0040,
+
+ ///
+ /// This type is generic and one or more of its type parameters is co- or contra-variant. This
+ /// only applies to interface and delegate types.
+ ///
+ GenericVarianceFlag = 0x0080,
+
+ ///
+ /// This type has optional fields present.
+ ///
+ OptionalFieldsFlag = 0x0100,
+
+ // Unused = 0x0200,
+
+ ///
+ /// This type is generic.
+ ///
+ IsGenericFlag = 0x0400,
+
+ ///
+ /// We are storing a EETypeElementType in the upper bits for unboxing enums.
+ ///
+ ElementTypeMask = 0xf800,
+ ElementTypeShift = 11,
+
+ ///
+ /// Single mark to check TypeKind and two flags. When non-zero, casting is more complicated.
+ ///
+ ComplexCastingMask = EETypeKindMask | RelatedTypeViaIATFlag | GenericVarianceFlag
+ };
+
+ internal enum EETypeKind : ushort
+ {
+ ///
+ /// Represents a standard ECMA type
+ ///
+ CanonicalEEType = 0x0000,
+
+ ///
+ /// Represents a type cloned from another EEType
+ ///
+ ClonedEEType = 0x0001,
+
+ ///
+ /// Represents a parameterized type. For example a single dimensional array or pointer type
+ ///
+ ParameterizedEEType = 0x0002,
+
+ ///
+ /// Represents an uninstantiated generic type definition
+ ///
+ GenericTypeDefEEType = 0x0003,
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ObjHeader
+ {
+ // Contents of the object header
+ private IntPtr _objHeaderContents;
+ }
+
+ // [StructLayout(LayoutKind.Sequential)]
+ // internal unsafe struct EEInterfaceInfo {
+ // [StructLayout(LayoutKind.Explicit)]
+ // private unsafe struct InterfaceTypeUnion {
+ // [FieldOffset(0)]
+ // public EEType* _pInterfaceEEType;
+ // [FieldOffset(0)]
+ // public EEType** _ppInterfaceEETypeViaIAT;
+ // }
+
+ // private InterfaceTypeUnion _interfaceType;
+
+ // internal EEType* InterfaceType {
+ // get {
+ // if ((unchecked((uint)_interfaceType._pInterfaceEEType) & IndirectionConstants.IndirectionCellPointer) != 0) {
+ //#if TARGET_64BIT
+ // EEType** ppInterfaceEETypeViaIAT = (EEType**)(((ulong)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer);
+ //#else
+ // EEType** ppInterfaceEETypeViaIAT = (EEType**)(((uint)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer);
+ //#endif
+ // return *ppInterfaceEETypeViaIAT;
+ // }
+
+ // return _interfaceType._pInterfaceEEType;
+ // }
+ //#if TYPE_LOADER_IMPLEMENTATION
+ // set
+ // {
+ // _interfaceType._pInterfaceEEType = value;
+ // }
+ //#endif
+ // }
+ // }
+
+ // [StructLayout(LayoutKind.Sequential)]
+ // internal unsafe struct DispatchMap {
+ // [StructLayout(LayoutKind.Sequential)]
+ // internal unsafe struct DispatchMapEntry {
+ // internal ushort _usInterfaceIndex;
+ // internal ushort _usInterfaceMethodSlot;
+ // internal ushort _usImplMethodSlot;
+ // }
+
+ // private uint _entryCount;
+ // private DispatchMapEntry _dispatchMap; // at least one entry if any interfaces defined
+
+ // public bool IsEmpty {
+ // get {
+ // return _entryCount == 0;
+ // }
+ // }
+
+ // public uint NumEntries {
+ // get {
+ // return _entryCount;
+ // }
+ //#if TYPE_LOADER_IMPLEMENTATION
+ // set
+ // {
+ // _entryCount = value;
+ // }
+ //#endif
+ // }
+
+ // public int Size {
+ // get {
+ // return sizeof(uint) + sizeof(DispatchMapEntry) * (int)_entryCount;
+ // }
+ // }
+
+ // public DispatchMapEntry* this[int index] {
+ // get {
+ // fixed (DispatchMap* pThis = &this)
+ // return (DispatchMapEntry*)((byte*)pThis + sizeof(uint) + (sizeof(DispatchMapEntry) * index));
+ // }
+ // }
+ // }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public unsafe struct EEType
+ {
+ private const int POINTER_SIZE = 8;
+ private const int PADDING = 1; // _numComponents is padded by one Int32 to make the first element pointer-aligned
+ internal const int SZARRAY_BASE_SIZE = POINTER_SIZE + POINTER_SIZE + (1 + PADDING) * 4;
+
+ [StructLayout(LayoutKind.Explicit)]
+ private unsafe struct RelatedTypeUnion
+ {
+ // Kinds.CanonicalEEType
+ [FieldOffset(0)]
+ public EEType* _pBaseType;
+ [FieldOffset(0)]
+ public EEType** _ppBaseTypeViaIAT;
+
+ // Kinds.ClonedEEType
+ [FieldOffset(0)]
+ public EEType* _pCanonicalType;
+ [FieldOffset(0)]
+ public EEType** _ppCanonicalTypeViaIAT;
+
+ // Kinds.ArrayEEType
+ [FieldOffset(0)]
+ public EEType* _pRelatedParameterType;
+ [FieldOffset(0)]
+ public EEType** _ppRelatedParameterTypeViaIAT;
+ }
+
+ //private static unsafe class OptionalFieldsReader {
+ // internal static uint GetInlineField(byte* pFields, EETypeOptionalFieldTag eTag, uint uiDefaultValue) {
+ // if (pFields == null)
+ // return uiDefaultValue;
+
+ // bool isLastField = false;
+ // while (!isLastField) {
+ // byte fieldHeader = NativePrimitiveDecoder.ReadUInt8(ref pFields);
+ // isLastField = (fieldHeader & 0x80) != 0;
+ // EETypeOptionalFieldTag eCurrentTag = (EETypeOptionalFieldTag)(fieldHeader & 0x7f);
+ // uint uiCurrentValue = NativePrimitiveDecoder.DecodeUnsigned(ref pFields);
+
+ // // If we found a tag match return the current value.
+ // if (eCurrentTag == eTag)
+ // return uiCurrentValue;
+ // }
+
+ // // Reached end of stream without getting a match. Field is not present so return default value.
+ // return uiDefaultValue;
+ // }
+ //}
+
+ /////
+ ///// Gets a value indicating whether the statically generated data structures use relative pointers.
+ /////
+ //internal static bool SupportsRelativePointers {
+ // [Intrinsic]
+ // get {
+ // throw new NotImplementedException();
+ // }
+ //}
+
+ private ushort _usComponentSize;
+ private ushort _usFlags;
+ private uint _uBaseSize;
+ private RelatedTypeUnion _relatedType;
+ private ushort _usNumVtableSlots;
+ private ushort _usNumInterfaces;
+ private uint _uHashCode;
+
+ // vtable follows
+
+ // These masks and paddings have been chosen so that the ValueTypePadding field can always fit in a byte of data.
+ // if the alignment is 8 bytes or less. If the alignment is higher then there may be a need for more bits to hold
+ // the rest of the padding data.
+ // If paddings of greater than 7 bytes are necessary, then the high bits of the field represent that padding
+ private const uint ValueTypePaddingLowMask = 0x7;
+ private const uint ValueTypePaddingHighMask = 0xFFFFFF00;
+ private const uint ValueTypePaddingMax = 0x07FFFFFF;
+ private const int ValueTypePaddingHighShift = 8;
+ private const uint ValueTypePaddingAlignmentMask = 0xF8;
+ private const int ValueTypePaddingAlignmentShift = 3;
+
+ internal ushort ComponentSize
+ {
+ get
+ {
+ return _usComponentSize;
+ }
+ }
+
+ //internal ushort GenericArgumentCount {
+ // get {
+ // Debug.Assert(IsGenericTypeDefinition);
+ // return _usComponentSize;
+ // }
+ //}
+
+ //internal ushort Flags {
+ // get {
+ // return _usFlags;
+ // }
+ //}
+
+ internal uint BaseSize
+ {
+ get
+ {
+ return _uBaseSize;
+ }
+ }
+
+ //internal ushort NumVtableSlots {
+ // get {
+ // return _usNumVtableSlots;
+ // }
+ //}
+
+ //internal ushort NumInterfaces {
+ // get {
+ // return _usNumInterfaces;
+ // }
+ //}
+
+ //internal uint HashCode {
+ // get {
+ // return _uHashCode;
+ // }
+ //}
+
+ private EETypeKind Kind
+ {
+ get
+ {
+ return (EETypeKind)(_usFlags & (ushort)EETypeFlags.EETypeKindMask);
+ }
+ }
+
+ //internal bool HasOptionalFields {
+ // get {
+ // return ((_usFlags & (ushort)EETypeFlags.OptionalFieldsFlag) != 0);
+ // }
+ //}
+
+ //// Mark or determine that a type is generic and one or more of it's type parameters is co- or
+ //// contra-variant. This only applies to interface and delegate types.
+ internal bool HasGenericVariance
+ {
+ get
+ {
+ return ((_usFlags & (ushort)EETypeFlags.GenericVarianceFlag) != 0);
+ }
+ }
+
+ //internal bool IsFinalizable {
+ // get {
+ // return ((_usFlags & (ushort)EETypeFlags.HasFinalizerFlag) != 0);
+ // }
+ //}
+
+ //internal bool IsNullable {
+ // get {
+ // return ElementType == EETypeElementType.Nullable;
+ // }
+ //}
+
+ internal bool IsCloned
+ {
+ get
+ {
+ return Kind == EETypeKind.ClonedEEType;
+ }
+ }
+
+ //internal bool IsCanonical {
+ // get {
+ // return Kind == EETypeKind.CanonicalEEType;
+ // }
+ //}
+
+ internal bool IsString
+ {
+ get
+ {
+ // String is currently the only non-array type with a non-zero component size.
+ return ComponentSize == sizeof(char) && !IsArray && !IsGenericTypeDefinition;
+ }
+ }
+
+ internal bool IsArray
+ {
+ get
+ {
+ EETypeElementType elementType = ElementType;
+ return elementType == EETypeElementType.Array || elementType == EETypeElementType.SzArray;
+ }
+ }
+
+ internal static class WellKnownEETypes
+ {
+ // Returns true if the passed in EEType is the EEType for System.Object
+ // This is recognized by the fact that System.Object and interfaces are the only ones without a base type
+ internal static unsafe bool IsSystemObject(EEType* pEEType)
+ {
+ if (pEEType->IsArray)
+ return false;
+ return (pEEType->NonArrayBaseType == null) && !pEEType->IsInterface;
+ }
+
+ // Returns true if the passed in EEType is the EEType for System.Array.
+ // The binder sets a special CorElementType for this well known type
+ internal static unsafe bool IsSystemArray(EEType* pEEType)
+ {
+ return (pEEType->ElementType == EETypeElementType.SystemArray);
+ }
+ }
+
+ internal int ArrayRank
+ {
+ get
+ {
+ int boundsSize = (int)this.ParameterizedTypeShape - SZARRAY_BASE_SIZE;
+ if (boundsSize > 0)
+ {
+ // Multidim array case: Base size includes space for two Int32s
+ // (upper and lower bound) per each dimension of the array.
+ return boundsSize / (2 * sizeof(int));
+ }
+ return 1;
+ }
+ }
+
+ internal bool IsSzArray
+ {
+ get
+ {
+ return ElementType == EETypeElementType.SzArray;
+ }
+ }
+
+ //internal bool IsGeneric {
+ // get {
+ // return ((_usFlags & (ushort)EETypeFlags.IsGenericFlag) != 0);
+ // }
+ //}
+
+ internal bool IsGenericTypeDefinition
+ {
+ get
+ {
+ return Kind == EETypeKind.GenericTypeDefEEType;
+ }
+ }
+
+ //internal EEType* GenericDefinition {
+ // get {
+ // Debug.Assert(IsGeneric);
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField>(EETypeField.ETF_GenericDefinition).Value;
+
+ // return GetField>(EETypeField.ETF_GenericDefinition).Value;
+ // }
+ //}
+
+ //[StructLayout(LayoutKind.Sequential)]
+ //private readonly struct GenericComposition {
+ // public readonly ushort Arity;
+
+ // private readonly EETypeRef _genericArgument1;
+ // public EETypeRef* GenericArguments {
+ // get {
+ // return (EETypeRef*)Unsafe.AsPointer(ref Unsafe.AsRef(in _genericArgument1));
+ // }
+ // }
+
+ // public GenericVariance* GenericVariance {
+ // get {
+ // // Generic variance directly follows the last generic argument
+ // return (GenericVariance*)(GenericArguments + Arity);
+ // }
+ // }
+ //}
+
+ //internal uint GenericArity {
+ // get {
+ // Debug.Assert(IsGeneric);
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->Arity;
+
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->Arity;
+ // }
+ //}
+
+ //internal EETypeRef* GenericArguments {
+ // get {
+ // Debug.Assert(IsGeneric);
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments;
+
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments;
+ // }
+ //}
+
+ //internal GenericVariance* GenericVariance {
+ // get {
+ // Debug.Assert(IsGeneric);
+
+ // if (!HasGenericVariance)
+ // return null;
+
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance;
+
+ // return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance;
+ // }
+ //}
+
+ //internal bool IsPointerType {
+ // get {
+ // return ElementType == EETypeElementType.Pointer;
+ // }
+ //}
+
+ //internal bool IsByRefType {
+ // get {
+ // return ElementType == EETypeElementType.ByRef;
+ // }
+ //}
+
+ internal bool IsInterface
+ {
+ get
+ {
+ return ElementType == EETypeElementType.Interface;
+ }
+ }
+
+ //internal bool IsAbstract {
+ // get {
+ // return IsInterface || (RareFlags & EETypeRareFlags.IsAbstractClassFlag) != 0;
+ // }
+ //}
+
+ //internal bool IsByRefLike {
+ // get {
+ // return (RareFlags & EETypeRareFlags.IsByRefLikeFlag) != 0;
+ // }
+ //}
+
+ //internal bool IsDynamicType {
+ // get {
+ // return (_usFlags & (ushort)EETypeFlags.IsDynamicTypeFlag) != 0;
+ // }
+ //}
+
+ //internal bool HasDynamicallyAllocatedDispatchMap {
+ // get {
+ // return (RareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0;
+ // }
+ //}
+
+ //internal bool IsParameterizedType {
+ // get {
+ // return Kind == EETypeKind.ParameterizedEEType;
+ // }
+ //}
+
+ //// The parameterized type shape defines the particular form of parameterized type that
+ //// is being represented.
+ //// Currently, the meaning is a shape of 0 indicates that this is a Pointer,
+ //// shape of 1 indicates a ByRef, and >=SZARRAY_BASE_SIZE indicates that this is an array.
+ //// Two types are not equivalent if their shapes do not exactly match.
+ internal uint ParameterizedTypeShape
+ {
+ get
+ {
+ return _uBaseSize;
+ }
+ }
+
+ internal bool IsRelatedTypeViaIAT
+ {
+ get
+ {
+ return ((_usFlags & (ushort)EETypeFlags.RelatedTypeViaIATFlag) != 0);
+ }
+ }
+
+ //internal bool RequiresAlign8 {
+ // get {
+ // return (RareFlags & EETypeRareFlags.RequiresAlign8Flag) != 0;
+ // }
+ //}
+
+ //internal bool IsICastable {
+ // get {
+ // return ((_usFlags & (ushort)EETypeFlags.ICastableFlag) != 0);
+ // }
+ //}
+
+ /////
+ ///// Gets the pointer to the method that implements ICastable.IsInstanceOfInterface.
+ /////
+ //internal IntPtr ICastableIsInstanceOfInterfaceMethod {
+ // get {
+ // Debug.Assert(IsICastable);
+
+ // byte* optionalFields = OptionalFieldsPtr;
+ // if (optionalFields != null) {
+ // const ushort NoSlot = 0xFFFF;
+ // ushort uiSlot = (ushort)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableIsInstSlot, NoSlot);
+ // if (uiSlot != NoSlot) {
+ // if (uiSlot < NumVtableSlots)
+ // return GetVTableStartAddress()[uiSlot];
+ // else
+ // return GetSealedVirtualSlot((ushort)(uiSlot - NumVtableSlots));
+ // }
+ // }
+
+ // EEType* baseType = BaseType;
+ // if (baseType != null)
+ // return baseType->ICastableIsInstanceOfInterfaceMethod;
+
+ // Debug.Assert(false);
+ // return IntPtr.Zero;
+ // }
+ //}
+
+ /////
+ ///// Gets the pointer to the method that implements ICastable.GetImplType.
+ /////
+ //internal IntPtr ICastableGetImplTypeMethod {
+ // get {
+ // Debug.Assert(IsICastable);
+
+ // byte* optionalFields = OptionalFieldsPtr;
+ // if (optionalFields != null) {
+ // const ushort NoSlot = 0xFFFF;
+ // ushort uiSlot = (ushort)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableGetImplTypeSlot, NoSlot);
+ // if (uiSlot != NoSlot) {
+ // if (uiSlot < NumVtableSlots)
+ // return GetVTableStartAddress()[uiSlot];
+ // else
+ // return GetSealedVirtualSlot((ushort)(uiSlot - NumVtableSlots));
+ // }
+ // }
+
+ // EEType* baseType = BaseType;
+ // if (baseType != null)
+ // return baseType->ICastableGetImplTypeMethod;
+
+ // Debug.Assert(false);
+ // return IntPtr.Zero;
+ // }
+ //}
+
+ //internal bool IsValueType {
+ // get {
+ // return ElementType < EETypeElementType.Class;
+ // }
+ //}
+
+ //internal bool HasGCPointers {
+ // get {
+ // return ((_usFlags & (ushort)EETypeFlags.HasPointersFlag) != 0);
+ // }
+ //}
+
+ //internal bool IsHFA {
+ // get {
+ // return (RareFlags & EETypeRareFlags.IsHFAFlag) != 0;
+ // }
+ //}
+
+ //internal uint ValueTypeFieldPadding {
+ // get {
+ // byte* optionalFields = OptionalFieldsPtr;
+
+ // // If there are no optional fields then the padding must have been the default, 0.
+ // if (optionalFields == null)
+ // return 0;
+
+ // // Get the value from the optional fields. The default is zero if that particular field was not included.
+ // // The low bits of this field is the ValueType field padding, the rest of the byte is the alignment if present
+ // uint ValueTypeFieldPaddingData = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0);
+ // uint padding = ValueTypeFieldPaddingData & ValueTypePaddingLowMask;
+ // // If there is additional padding, the other bits have that data
+ // padding |= (ValueTypeFieldPaddingData & ValueTypePaddingHighMask) >> (ValueTypePaddingHighShift - ValueTypePaddingAlignmentShift);
+ // return padding;
+ // }
+ //}
+
+ //internal uint ValueTypeSize {
+ // get {
+ // Debug.Assert(IsValueType);
+ // // get_BaseSize returns the GC size including space for the sync block index field, the EEType* and
+ // // padding for GC heap alignment. Must subtract all of these to get the size used for locals, array
+ // // elements or fields of another type.
+ // return BaseSize - ((uint)sizeof(ObjHeader) + (uint)sizeof(EEType*) + ValueTypeFieldPadding);
+ // }
+ //}
+
+ //internal uint FieldByteCountNonGCAligned {
+ // get {
+ // // This api is designed to return correct results for EETypes which can be derived from
+ // // And results indistinguishable from correct for DefTypes which cannot be derived from (sealed classes)
+ // // (For sealed classes, this should always return BaseSize-((uint)sizeof(ObjHeader));
+ // Debug.Assert(!IsInterface && !IsParameterizedType);
+
+ // // get_BaseSize returns the GC size including space for the sync block index field, the EEType* and
+ // // padding for GC heap alignment. Must subtract all of these to get the size used for the fields of
+ // // the type (where the fields of the type includes the EEType*)
+ // return BaseSize - ((uint)sizeof(ObjHeader) + ValueTypeFieldPadding);
+ // }
+ //}
+
+ //internal EEInterfaceInfo* InterfaceMap {
+ // get {
+ // fixed (EEType* start = &this) {
+ // // interface info table starts after the vtable and has _usNumInterfaces entries
+ // return (EEInterfaceInfo*)((byte*)start + sizeof(EEType) + sizeof(void*) * _usNumVtableSlots);
+ // }
+ // }
+ //}
+
+ //internal bool HasDispatchMap {
+ // get {
+ // if (NumInterfaces == 0)
+ // return false;
+ // byte* optionalFields = OptionalFieldsPtr;
+ // if (optionalFields == null)
+ // return false;
+ // uint idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff);
+ // if (idxDispatchMap == 0xffffffff) {
+ // if (HasDynamicallyAllocatedDispatchMap)
+ // return true;
+ // else if (IsDynamicType)
+ // return DynamicTemplateType->HasDispatchMap;
+ // return false;
+ // }
+ // return true;
+ // }
+ //}
+
+ //internal DispatchMap* DispatchMap {
+ // get {
+ // if (NumInterfaces == 0)
+ // return null;
+ // byte* optionalFields = OptionalFieldsPtr;
+ // if (optionalFields == null)
+ // return null;
+ // uint idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff);
+ // if (idxDispatchMap == 0xffffffff && IsDynamicType) {
+ // if (HasDynamicallyAllocatedDispatchMap) {
+ // fixed (EEType* pThis = &this)
+ // return *(DispatchMap**)((byte*)pThis + GetFieldOffset(EETypeField.ETF_DynamicDispatchMap));
+ // }
+ // else
+ // return DynamicTemplateType->DispatchMap;
+ // }
+
+ // return ((DispatchMap**)TypeManager.DispatchMap)[idxDispatchMap];
+ // }
+ //}
+
+ //// Get the address of the finalizer method for finalizable types.
+ //internal IntPtr FinalizerCode {
+ // get {
+ // Debug.Assert(IsFinalizable);
+
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField(EETypeField.ETF_Finalizer).Value;
+
+ // return GetField(EETypeField.ETF_Finalizer).Value;
+ // }
+ //}
+
+ //internal EEType* BaseType {
+ // get {
+ // if (IsCloned) {
+ // return CanonicalEEType->BaseType;
+ // }
+
+ // if (IsParameterizedType) {
+ // if (IsArray)
+ // return GetArrayEEType();
+ // else
+ // return null;
+ // }
+
+ // Debug.Assert(IsCanonical);
+
+ // if (IsRelatedTypeViaIAT)
+ // return *_relatedType._ppBaseTypeViaIAT;
+ // else
+ // return _relatedType._pBaseType;
+ // }
+ //}
+
+ internal EEType* NonArrayBaseType
+ {
+ get
+ {
+ if (IsCloned)
+ {
+ // Assuming that since this is not an Array, the CanonicalEEType is also not an array
+ return CanonicalEEType->NonArrayBaseType;
+ }
+
+ if (IsRelatedTypeViaIAT)
+ {
+ return *_relatedType._ppBaseTypeViaIAT;
+ }
+
+ return _relatedType._pBaseType;
+ }
+ }
+
+ internal EEType* NonClonedNonArrayBaseType
+ {
+ get
+ {
+ if (IsRelatedTypeViaIAT)
+ {
+ return *_relatedType._ppBaseTypeViaIAT;
+ }
+
+ return _relatedType._pBaseType;
+ }
+ }
+
+ internal EEType* RawBaseType
+ {
+ get
+ {
+ //Debug.Assert(!IsParameterizedType, "array type not supported in NonArrayBaseType");
+ //Debug.Assert(!IsCloned, "cloned type not supported in NonClonedNonArrayBaseType");
+ //Debug.Assert(IsCanonical, "we expect canonical types here");
+ //Debug.Assert(!IsRelatedTypeViaIAT, "Non IAT");
+
+ return _relatedType._pBaseType;
+ }
+ }
+
+ internal EEType* CanonicalEEType
+ {
+ get
+ {
+ // cloned EETypes must always refer to types in other modules
+ if (IsRelatedTypeViaIAT)
+ return *_relatedType._ppCanonicalTypeViaIAT;
+ else
+ return _relatedType._pCanonicalType;
+ }
+ }
+
+ //internal EEType* NullableType {
+ // get {
+ // Debug.Assert(IsNullable);
+ // Debug.Assert(GenericArity == 1);
+ // return GenericArguments[0].Value;
+ // }
+ //}
+
+ /////
+ ///// Gets the offset of the value embedded in a Nullable<T>.
+ /////
+ //internal byte NullableValueOffset {
+ // get {
+ // Debug.Assert(IsNullable);
+
+ // // Grab optional fields. If there aren't any then the offset was the default of 1 (immediately after the
+ // // Nullable's boolean flag).
+ // byte* optionalFields = OptionalFieldsPtr;
+ // if (optionalFields == null)
+ // return 1;
+
+ // // The offset is never zero (Nullable has a boolean there indicating whether the value is valid). So the
+ // // offset is encoded - 1 to save space. The zero below is the default value if the field wasn't encoded at
+ // // all.
+ // return (byte)(OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.NullableValueOffset, 0) + 1);
+ // }
+ //}
+
+ internal EEType* RelatedParameterType
+ {
+ get
+ {
+ if (IsRelatedTypeViaIAT)
+ return *_relatedType._ppRelatedParameterTypeViaIAT;
+ else
+ return _relatedType._pRelatedParameterType;
+ }
+ }
+
+ //internal unsafe IntPtr* GetVTableStartAddress() {
+ // byte* pResult;
+
+ // // EETypes are always in unmanaged memory, so 'leaking' the 'fixed pointer' is safe.
+ // fixed (EEType* pThis = &this)
+ // pResult = (byte*)pThis;
+
+ // pResult += sizeof(EEType);
+ // return (IntPtr*)pResult;
+ //}
+
+ //private static IntPtr FollowRelativePointer(int* pDist) {
+ // int dist = *pDist;
+ // IntPtr result = (IntPtr)((byte*)pDist + dist);
+ // return result;
+ //}
+
+ //internal IntPtr GetSealedVirtualSlot(ushort slotNumber) {
+ // Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0);
+
+ // fixed (EEType* pThis = &this) {
+ // if (IsDynamicType || !SupportsRelativePointers) {
+ // uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
+ // IntPtr* pSealedVirtualsSlotTable = *(IntPtr**)((byte*)pThis + cbSealedVirtualSlotsTypeOffset);
+ // return pSealedVirtualsSlotTable[slotNumber];
+ // }
+ // else {
+ // uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
+ // int* pSealedVirtualsSlotTable = (int*)FollowRelativePointer((int*)((byte*)pThis + cbSealedVirtualSlotsTypeOffset));
+ // IntPtr result = FollowRelativePointer(&pSealedVirtualsSlotTable[slotNumber]);
+ // return result;
+ // }
+ // }
+ //}
+
+ //internal byte* OptionalFieldsPtr {
+ // get {
+ // if (!HasOptionalFields)
+ // return null;
+
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // return GetField>(EETypeField.ETF_OptionalFieldsPtr).Value;
+
+ // return GetField>(EETypeField.ETF_OptionalFieldsPtr).Value;
+ // }
+ //}
+
+ //internal EEType* DynamicTemplateType {
+ // get {
+ // Debug.Assert(IsDynamicType);
+ // uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicTemplateType);
+ // fixed (EEType* pThis = &this) {
+ // return *(EEType**)((byte*)pThis + cbOffset);
+ // }
+ // }
+ //}
+
+ //internal IntPtr DynamicGcStaticsData {
+ // get {
+ // Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
+ // uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicGcStatics);
+ // fixed (EEType* pThis = &this) {
+ // return (IntPtr)((byte*)pThis + cbOffset);
+ // }
+ // }
+ //}
+
+ //internal IntPtr DynamicNonGcStaticsData {
+ // get {
+ // Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0);
+ // uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicNonGcStatics);
+ // fixed (EEType* pThis = &this) {
+ // return (IntPtr)((byte*)pThis + cbOffset);
+ // }
+ // }
+ //}
+
+ //internal DynamicModule* DynamicModule {
+ // get {
+ // if ((RareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0) {
+ // uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicModule);
+ // fixed (EEType* pThis = &this) {
+ // return *(DynamicModule**)((byte*)pThis + cbOffset);
+ // }
+ // }
+ // else {
+ // return null;
+ // }
+ // }
+ //}
+
+ //internal TypeManagerHandle TypeManager {
+ // get {
+ // IntPtr typeManagerIndirection;
+ // if (IsDynamicType || !SupportsRelativePointers)
+ // typeManagerIndirection = GetField(EETypeField.ETF_TypeManagerIndirection).Value;
+ // else
+ // typeManagerIndirection = GetField(EETypeField.ETF_TypeManagerIndirection).Value;
+
+ // return *(TypeManagerHandle*)typeManagerIndirection;
+ // }
+ //}
+
+ //internal unsafe EETypeRareFlags RareFlags {
+ // get {
+ // // If there are no optional fields then none of the rare flags have been set.
+ // // Get the flags from the optional fields. The default is zero if that particular field was not included.
+ // return HasOptionalFields ? (EETypeRareFlags)OptionalFieldsReader.GetInlineField(OptionalFieldsPtr, EETypeOptionalFieldTag.RareFlags, 0) : 0;
+ // }
+ //}
+
+ //internal int FieldAlignmentRequirement {
+ // get {
+ // byte* optionalFields = OptionalFieldsPtr;
+
+ // // If there are no optional fields then the alignment must have been the default, IntPtr.Size.
+ // // (This happens for all reference types, and for valuetypes with default alignment and no padding)
+ // if (optionalFields == null)
+ // return IntPtr.Size;
+
+ // // Get the value from the optional fields. The default is zero if that particular field was not included.
+ // // The low bits of this field is the ValueType field padding, the rest of the value is the alignment if present
+ // uint alignmentValue = (OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0) & ValueTypePaddingAlignmentMask) >> ValueTypePaddingAlignmentShift;
+
+ // // Alignment is stored as 1 + the log base 2 of the alignment, except a 0 indicates standard pointer alignment.
+ // if (alignmentValue == 0)
+ // return IntPtr.Size;
+ // else
+ // return 1 << ((int)alignmentValue - 1);
+ // }
+ //}
+
+ internal EETypeElementType ElementType
+ {
+ get
+ {
+ return (EETypeElementType)((_usFlags & (ushort)EETypeFlags.ElementTypeMask) >> (ushort)EETypeFlags.ElementTypeShift);
+ }
+ }
+
+ //public bool HasCctor {
+ // get {
+ // return (RareFlags & EETypeRareFlags.HasCctorFlag) != 0;
+ // }
+ //}
+
+ //public uint GetFieldOffset(EETypeField eField) {
+ // // First part of EEType consists of the fixed portion followed by the vtable.
+ // uint cbOffset = (uint)(sizeof(EEType) + (IntPtr.Size * _usNumVtableSlots));
+
+ // // Then we have the interface map.
+ // if (eField == EETypeField.ETF_InterfaceMap) {
+ // Debug.Assert(NumInterfaces > 0);
+ // return cbOffset;
+ // }
+ // cbOffset += (uint)(sizeof(EEInterfaceInfo) * NumInterfaces);
+
+ // uint relativeOrFullPointerOffset = (IsDynamicType || !SupportsRelativePointers ? (uint)IntPtr.Size : 4);
+
+ // // Followed by the type manager indirection cell.
+ // if (eField == EETypeField.ETF_TypeManagerIndirection) {
+ // return cbOffset;
+ // }
+ // cbOffset += relativeOrFullPointerOffset;
+
+ // // Followed by the pointer to the finalizer method.
+ // if (eField == EETypeField.ETF_Finalizer) {
+ // Debug.Assert(IsFinalizable);
+ // return cbOffset;
+ // }
+ // if (IsFinalizable)
+ // cbOffset += relativeOrFullPointerOffset;
+
+ // // Followed by the pointer to the optional fields.
+ // if (eField == EETypeField.ETF_OptionalFieldsPtr) {
+ // Debug.Assert(HasOptionalFields);
+ // return cbOffset;
+ // }
+ // if (HasOptionalFields)
+ // cbOffset += relativeOrFullPointerOffset;
+
+ // // Followed by the pointer to the sealed virtual slots
+ // if (eField == EETypeField.ETF_SealedVirtualSlots)
+ // return cbOffset;
+
+ // EETypeRareFlags rareFlags = RareFlags;
+
+ // // in the case of sealed vtable entries on static types, we have a UInt sized relative pointer
+ // if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
+ // cbOffset += relativeOrFullPointerOffset;
+
+ // if (eField == EETypeField.ETF_DynamicDispatchMap) {
+ // Debug.Assert(IsDynamicType);
+ // return cbOffset;
+ // }
+ // if ((rareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0)
+ // cbOffset += (uint)IntPtr.Size;
+
+ // if (eField == EETypeField.ETF_GenericDefinition) {
+ // Debug.Assert(IsGeneric);
+ // return cbOffset;
+ // }
+ // if (IsGeneric) {
+ // cbOffset += relativeOrFullPointerOffset;
+ // }
+
+ // if (eField == EETypeField.ETF_GenericComposition) {
+ // Debug.Assert(IsGeneric);
+ // return cbOffset;
+ // }
+ // if (IsGeneric) {
+ // cbOffset += relativeOrFullPointerOffset;
+ // }
+
+ // if (eField == EETypeField.ETF_DynamicModule) {
+ // return cbOffset;
+ // }
+
+ // if ((rareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0)
+ // cbOffset += (uint)IntPtr.Size;
+
+ // if (eField == EETypeField.ETF_DynamicTemplateType) {
+ // Debug.Assert(IsDynamicType);
+ // return cbOffset;
+ // }
+ // if (IsDynamicType)
+ // cbOffset += (uint)IntPtr.Size;
+
+ // if (eField == EETypeField.ETF_DynamicGcStatics) {
+ // Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
+ // return cbOffset;
+ // }
+ // if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0)
+ // cbOffset += (uint)IntPtr.Size;
+
+ // if (eField == EETypeField.ETF_DynamicNonGcStatics) {
+ // Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0);
+ // return cbOffset;
+ // }
+ // if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
+ // cbOffset += (uint)IntPtr.Size;
+
+ // if (eField == EETypeField.ETF_DynamicThreadStaticOffset) {
+ // Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0);
+ // return cbOffset;
+ // }
+ // if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0)
+ // cbOffset += 4;
+
+ // Debug.Assert(false, "Unknown EEType field type");
+ // return 0;
+ //}
+
+ //public ref T GetField(EETypeField eField) {
+ // fixed (EEType* pThis = &this)
+ // return ref Unsafe.AddByteOffset(ref Unsafe.As(ref *pThis), (IntPtr)GetFieldOffset(eField));
+ //}
+ }
+
+ //// Wrapper around EEType pointers that may be indirected through the IAT if their low bit is set.
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal unsafe struct EETypeRef {
+ // private byte* _value;
+
+ // public EEType* Value {
+ // get {
+ // if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0)
+ // return (EEType*)_value;
+ // return *(EEType**)(_value - IndirectionConstants.IndirectionCellPointer);
+ // }
+ // }
+ //}
+
+ //// Wrapper around pointers
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal readonly struct Pointer {
+ // private readonly IntPtr _value;
+
+ // public IntPtr Value {
+ // get {
+ // return _value;
+ // }
+ // }
+ //}
+
+ //// Wrapper around pointers
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal unsafe readonly struct Pointer where T : unmanaged {
+ // private readonly T* _value;
+
+ // public T* Value {
+ // get {
+ // return _value;
+ // }
+ // }
+ //}
+
+ //// Wrapper around pointers that might be indirected through IAT
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal unsafe readonly struct IatAwarePointer where T : unmanaged {
+ // private readonly T* _value;
+
+ // public T* Value {
+ // get {
+ // if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0)
+ // return _value;
+ // return *(T**)((byte*)_value - IndirectionConstants.IndirectionCellPointer);
+ // }
+ // }
+ //}
+
+ //// Wrapper around relative pointers
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal readonly struct RelativePointer {
+ // private readonly int _value;
+
+ // public unsafe IntPtr Value {
+ // get {
+ // return (IntPtr)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value);
+ // }
+ // }
+ //}
+
+ //// Wrapper around relative pointers
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal unsafe readonly struct RelativePointer where T : unmanaged {
+ // private readonly int _value;
+
+ // public T* Value {
+ // get {
+ // return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value);
+ // }
+ // }
+ //}
+
+ //// Wrapper around relative pointers that might be indirected through IAT
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal unsafe readonly struct IatAwareRelativePointer where T : unmanaged {
+ // private readonly int _value;
+
+ // public T* Value {
+ // get {
+ // if ((_value & IndirectionConstants.IndirectionCellPointer) == 0) {
+ // return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value);
+ // }
+ // else {
+ // return *(T**)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + (_value & ~IndirectionConstants.IndirectionCellPointer));
+ // }
+ // }
+ // }
+ //}
+
+ //[StructLayout(LayoutKind.Sequential)]
+ //internal struct DynamicModule {
+ // // Size field used to indicate the number of bytes of this structure that are defined in Runtime Known ways
+ // // This is used to drive versioning of this field
+ // private int _cbSize;
+
+ // // Pointer to interface dispatch resolver that works off of a type/slot pair
+ // // This is a function pointer with the following signature IntPtr()(IntPtr targetType, IntPtr interfaceType, ushort slot)
+ // private IntPtr _dynamicTypeSlotDispatchResolve;
+
+ // // Starting address for the the binary module corresponding to this dynamic module.
+ // private IntPtr _getRuntimeException;
+
+ // public IntPtr DynamicTypeSlotDispatchResolve {
+ // get {
+ // unsafe {
+ // if (_cbSize >= sizeof(IntPtr) * 2) {
+ // return _dynamicTypeSlotDispatchResolve;
+ // }
+ // else {
+ // return IntPtr.Zero;
+ // }
+ // }
+ // }
+ // }
+
+ // public IntPtr GetRuntimeException {
+ // get {
+ // unsafe {
+ // if (_cbSize >= sizeof(IntPtr) * 3) {
+ // return _getRuntimeException;
+ // }
+ // else {
+ // return IntPtr.Zero;
+ // }
+ // }
+ // }
+ // }
+ //}
+}
\ No newline at end of file
diff --git a/source/Lib.c b/source/Lib.c
new file mode 100644
index 0000000..221ff9e
--- /dev/null
+++ b/source/Lib.c
@@ -0,0 +1,21 @@
+#include "Lib.h"
+
+int printf(const char *string, ...)
+{
+ asm volatile ("mov $0x01, %%eax\n" //Print function
+ "mov %0, %%edi\n" //mov string pointer to ESI
+ "int $0x48\n" //interrupt 0x48 (Aura API)
+ :
+ : "r"(string)
+ : "edi", "eax", "memory");
+ return 1;
+}
+
+void clear()
+{
+ asm volatile ("mov $0x02, %%eax\n" //Clear function
+ "int $0x48\n" //interrupt 0x48 (Aura API)
+ :
+ :
+ : "eax", "memory");
+}
\ No newline at end of file
diff --git a/source/lib/stdio.h b/source/Lib.h
similarity index 59%
rename from source/lib/stdio.h
rename to source/Lib.h
index 95d37c7..1df533a 100644
--- a/source/lib/stdio.h
+++ b/source/Lib.h
@@ -2,6 +2,7 @@
#define __STDIO_H__
int printf(const char *, ...);
-char *fgets(char *string);
+void clear();
+int strlen(char const *str);
-#endif
+#endif
\ No newline at end of file
diff --git a/source/Makefile b/source/Makefile
new file mode 100644
index 0000000..380a162
--- /dev/null
+++ b/source/Makefile
@@ -0,0 +1,54 @@
+.PHONY: build run clean debug
+
+ILC=/mnt/c/Users/valentinbreiz/.nuget/packages/runtime.win-x64.microsoft.dotnet.ilcompiler/7.0.0-alpha.1.21430.2/tools/ilc.exe
+DOTNET = dotnet
+CC = gcc
+
+CFLAGS = -std=gnu99 -Os -nostdlib -m32 -ffreestanding -fno-PIC
+LDFLAGS = -m i386pe --nmagic -no-PIE --entry Main
+
+OBJ_DIR=obj
+
+C_SOURCES = $(wildcard *.c)
+OS_SOURCES = $(wildcard *.cs)
+
+OS_DLL=bin/Debug/net6.0/noruntime.dll
+OS_OBJ=obj/noruntime.o
+EXECUTABLE=bin/noruntime.exe
+
+_OBJ = $(C_SOURCES:.c=.o)
+OBJ = $(patsubst %,$(OBJ_DIR)/%,$(_OBJ))
+
+build: $(EXECUTABLE)
+ @echo Done building executable!;
+
+$(EXECUTABLE): $(OS_OBJ) $(OBJ)
+ @echo Linking $(EXECUTABLE); \
+ ld $(LDFLAGS) --output=$(EXECUTABLE) $(OBJ_DIR)/Lib.o $(OS_OBJ)
+
+$(OS_OBJ): $(OS_DLL)
+ @echo Converting CIL to native code; \
+ $(ILC) --targetarch x86 --systemmodule noruntime --out $(OS_OBJ) $(OS_DLL)
+
+$(OBJ_DIR): $(OBJ_DIR)
+ @mkdir $(OBJ_DIR)
+
+$(OBJ_DIR)/%.o: $(C_SOURCES)
+ @echo Assembling $@; \
+ $(CC) -c -o $@ $< $(CFLAGS)
+
+$(OS_DLL): $(OS_SOURCES)
+ @echo Building executable dlls; \
+ $(DOTNET) restore && \
+ $(DOTNET) build
+
+clean:
+ rm -rf *.log
+ rm -rf *.map
+ rm -rf obj/
+ rm -rf bin/
+ rm -rf *.o
+
+re: clean build
+
+print-% : ; @echo $* = $($*)
\ No newline at end of file
diff --git a/source/Program.cs b/source/Program.cs
new file mode 100644
index 0000000..d9e78ea
--- /dev/null
+++ b/source/Program.cs
@@ -0,0 +1,13 @@
+namespace SampleProgram
+{
+ public class Program
+ {
+ [System.Runtime.RuntimeExport("Main")]
+ static void Main()
+ {
+ //Console.Clear();
+ Console.WriteLine("Hello from a Portable Executable!\n");
+ Console.WriteLine("Compiled using NativeAOT and .NET 6\n");
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Runtime.cs b/source/Runtime.cs
new file mode 100644
index 0000000..b256c77
--- /dev/null
+++ b/source/Runtime.cs
@@ -0,0 +1,475 @@
+using Internal.Runtime;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#region A couple very basic things
+namespace System
+{
+ public sealed class FlagsAttribute : Attribute { }
+
+ public sealed class AttributeUsageAttribute : Attribute
+ {
+ public AttributeTargets ValidOn { get; set; }
+ public bool AllowMultiple { get; set; }
+ public bool Inherited { get; set; }
+
+ public AttributeUsageAttribute(AttributeTargets validOn)
+ {
+ ValidOn = validOn;
+ Inherited = true;
+ }
+
+ public AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited)
+ {
+ ValidOn = validOn;
+ AllowMultiple = allowMultiple;
+ Inherited = inherited;
+ }
+ }
+
+ public enum AttributeTargets
+ {
+ Assembly = 0x0001,
+ Module = 0x0002,
+ Class = 0x0004,
+ Struct = 0x0008,
+ Enum = 0x0010,
+ Constructor = 0x0020,
+ Method = 0x0040,
+ Property = 0x0080,
+ Field = 0x0100,
+ Event = 0x0200,
+ Interface = 0x0400,
+ Parameter = 0x0800,
+ Delegate = 0x1000,
+ ReturnValue = 0x2000,
+ GenericParameter = 0x4000,
+
+ All = Assembly | Module | Class | Struct | Enum | Constructor |
+ Method | Property | Field | Event | Interface | Parameter |
+ Delegate | ReturnValue | GenericParameter
+ }
+
+ public unsafe class Object
+ {
+ // The layout of object is a contract with the compiler.
+ internal unsafe EEType* m_pEEType;
+
+ [StructLayout(LayoutKind.Sequential)]
+ private class RawData
+ {
+ public byte Data;
+ }
+
+ internal ref byte GetRawData()
+ {
+ return ref Unsafe.As(this).Data;
+ }
+
+ internal uint GetRawDataSize()
+ {
+ return m_pEEType->BaseSize - (uint)sizeof(ObjHeader) - (uint)sizeof(EEType*);
+ }
+
+ public Object() { }
+ ~Object() { }
+
+
+ public virtual bool Equals(object o)
+ => false;
+
+ public virtual int GetHashCode()
+ => 0;
+
+ public virtual string ToString()
+ => "{object}";
+
+
+ public virtual void Dispose()
+ {
+ var obj = this;
+ //Allocator.Free(Unsafe.As