diff --git a/Iril/Compilation.cs b/Iril/Compilation.cs index f3148d9..e67b1de 100644 --- a/Iril/Compilation.cs +++ b/Iril/Compilation.cs @@ -89,6 +89,26 @@ public class Compilation public MethodReference sysMathFloorD; public MethodReference sysMathSqrtD; public MethodReference sysMathPowD; + public MethodReference sysMathMinSByte; + public MethodReference sysMathMinInt16; + public MethodReference sysMathMinInt32; + public MethodReference sysMathMinInt64; + public MethodReference sysMathMinByte; + public MethodReference sysMathMinUInt16; + public MethodReference sysMathMinUInt32; + public MethodReference sysMathMinUInt64; + public MethodReference sysMathMinS; + public MethodReference sysMathMinD; + public MethodReference sysMathMaxSByte; + public MethodReference sysMathMaxInt16; + public MethodReference sysMathMaxInt32; + public MethodReference sysMathMaxInt64; + public MethodReference sysMathMaxByte; + public MethodReference sysMathMaxUInt16; + public MethodReference sysMathMaxUInt32; + public MethodReference sysMathMaxUInt64; + public MethodReference sysMathMaxS; + public MethodReference sysMathMaxD; public MethodReference sysSingleIsNaN; public MethodReference sysDoubleIsNaN; TypeReference sysEventArgs; @@ -191,7 +211,8 @@ public MethodDefinition GetSystemMethod (Symbol symbol) f.ReferenceCount++; return f.ILDefinition; } - throw new KeyNotFoundException ($"Failed to find system method `{symbol}`"); + var methods = String.Join(", ", externalMethodDefs.Select(x => x.Key)); + throw new KeyNotFoundException ($"Failed to find system method `{symbol}` ({symbol.GetType()}): {methods}"); } readonly Lazy dataType; @@ -360,6 +381,26 @@ void FindSystemTypes () sysMathFloorD = ImportMethod (sysMath, sysDouble, "Floor", sysDouble); sysMathSqrtD = ImportMethod (sysMath, sysDouble, "Sqrt", sysDouble); sysMathPowD = ImportMethod (sysMath, sysDouble, "Pow", sysDouble, sysDouble); + sysMathMaxSByte = ImportMethod (sysMath, sysSByte, "Max", sysSByte, sysSByte); + sysMathMaxInt16 = ImportMethod (sysMath, sysInt16, "Max", sysInt16, sysInt16); + sysMathMaxInt32 = ImportMethod (sysMath, sysInt32, "Max", sysInt32, sysInt32); + sysMathMaxInt64 = ImportMethod (sysMath, sysInt64, "Max", sysInt64, sysInt64); + sysMathMaxByte = ImportMethod (sysMath, sysByte, "Max", sysByte, sysByte); + sysMathMaxUInt16 = ImportMethod (sysMath, sysUInt16, "Max", sysUInt16, sysUInt16); + sysMathMaxUInt32 = ImportMethod (sysMath, sysUInt32, "Max", sysUInt32, sysUInt32); + sysMathMaxUInt64 = ImportMethod (sysMath, sysUInt64, "Max", sysUInt64, sysUInt64); + sysMathMaxS = ImportMethod (sysMath, sysSingle, "Max", sysSingle, sysSingle); + sysMathMaxD = ImportMethod (sysMath, sysDouble, "Max", sysDouble, sysDouble); + sysMathMinSByte = ImportMethod (sysMath, sysSByte, "Min", sysSByte, sysSByte); + sysMathMinInt16 = ImportMethod (sysMath, sysInt16, "Min", sysInt16, sysInt16); + sysMathMinInt32 = ImportMethod (sysMath, sysInt32, "Min", sysInt32, sysInt32); + sysMathMinInt64 = ImportMethod (sysMath, sysInt64, "Min", sysInt64, sysInt64); + sysMathMinByte = ImportMethod (sysMath, sysByte, "Min", sysByte, sysByte); + sysMathMinUInt16 = ImportMethod (sysMath, sysUInt16, "Min", sysUInt16, sysUInt16); + sysMathMinUInt32 = ImportMethod (sysMath, sysUInt32, "Min", sysUInt32, sysUInt32); + sysMathMinUInt64 = ImportMethod (sysMath, sysUInt64, "Min", sysUInt64, sysUInt64); + sysMathMinS = ImportMethod (sysMath, sysSingle, "Min", sysSingle, sysSingle); + sysMathMinD = ImportMethod (sysMath, sysDouble, "Min", sysDouble, sysDouble); sysEventArgs = Import ("System.EventArgs"); sysIAsyncResult = Import ("System.IAsyncResult"); sysAsyncCallback = Import ("System.AsyncCallback"); @@ -1073,7 +1114,7 @@ TypeDefinition ImportType (TypeDefinition type, Action add) continue; var symbol = export != null ? Symbol.Intern (export.ConstructorArguments[0].Value.ToString ()) : null; - + var (im, imImport) = ImportTypeMethod (m, it, symbol); if (im == null) continue; @@ -1081,8 +1122,6 @@ TypeDefinition ImportType (TypeDefinition type, Action add) importMethodBodies.Add (imImport); if (export != null) { - - externalMethodDefs[symbol] = new DefinedFunction { Symbol = symbol, IRModule = null, @@ -1090,6 +1129,7 @@ TypeDefinition ImportType (TypeDefinition type, Action add) ILDefinition = im, ParamSyms = new SymbolTable (), }; + // Console.WriteLine($"FOUND EXPORT `{symbol}` ({symbol.GetType()})"); } else if (im.IsConstructor) { // OK diff --git a/Iril/FunctionCompiler.cs b/Iril/FunctionCompiler.cs index 57d25f5..41f9410 100644 --- a/Iril/FunctionCompiler.cs +++ b/Iril/FunctionCompiler.cs @@ -1075,7 +1075,7 @@ void EmitInstruction(LocalSymbol assignedSymbol, IR.Instruction instruction, IR. //if (cbr.IfFalse.Symbol != nextBlock?.Symbol) var falseDest = GetLabel (cbr.IfFalse, block, context); if (context.IsExceptionHandler && !context.IsProtecting (cbr.IfFalse)) { - Console.WriteLine ("EMIT FARLSE"); + // Console.WriteLine ("EMIT FALSE"); Emit (il.Create (OpCodes.Leave, falseDest)); } else { @@ -2450,9 +2450,15 @@ void EmitCall(IR.CallInstruction call, Block fromBlock) { if (call.Pointer is IR.GlobalValue gv) { switch (gv.Symbol.Text) { - case "@llvm.lifetime.start.p0i8": - case "@llvm.lifetime.end.p0i8": + case "@llvm.ceil.f64": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathCeilD)); + return; + case "@llvm.ceil.v2f64" when call.Arguments[0].Type is VectorType ceilVt: + EmitVectorFunc (call.Arguments[0].Value, ceilVt, compilation.sysMathCeilD); + return; case "@llvm.dbg.declare": + case "@llvm.dbg.label": return; case "@llvm.dbg.value": // call void @llvm.dbg.value(metadata %struct._parser_t* %3, metadata !1020, metadata !DIExpression(DW_OP_deref)), !dbg !1140 @@ -2473,25 +2479,18 @@ void EmitCall(IR.CallInstruction call, Block fromBlock) } } return; - case "@llvm.ceil.f64": - EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); - Emit (il.Create (OpCodes.Call, compilation.sysMathCeilD)); - return; - case "@llvm.ceil.v2f64" when call.Arguments[0].Type is VectorType ceilVt: - EmitVectorFunc (call.Arguments[0].Value, ceilVt, compilation.sysMathCeilD); - return; case "@llvm.fabs.f64": EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); Emit (il.Create (OpCodes.Call, compilation.sysMathAbsD)); return; - case "@llvm.sqrt.f64": - EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); - Emit (il.Create (OpCodes.Call, compilation.sysMathSqrtD)); - return; - case "@llvm.pow.f64": + case "@llvm.fshl.i64": EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); - Emit (il.Create (OpCodes.Call, compilation.sysMathPowD)); + EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); + Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol))); + return; + case "@llvm.lifetime.start.p0i8": + case "@llvm.lifetime.end.p0i8": return; case "@llvm.objectsize.i32.p0i8" when call.Arguments.Length >= 3: { var min = 0; @@ -2519,6 +2518,31 @@ void EmitCall(IR.CallInstruction call, Block fromBlock) } } return; + // declare void @llvm.memcpy.p0i8.p0i8.i32(i8* , i8* , + // i32 , i1 ) + case "@llvm.memcpy.p0i8.p0i8.i32" when call.Arguments.Length >= 3: + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); + Emit (il.Create (OpCodes.Cpblk)); + return; + // declare void @llvm.memcpy.p0i8.p0i8.i64(i8* , i8* , + // i64 , i1 ) + case "@llvm.memcpy.p0i8.p0i8.i64" when call.Arguments.Length >= 3: + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); + Emit (il.Create (OpCodes.Conv_U4)); + Emit (il.Create (OpCodes.Cpblk)); + return; + // declare void @llvm.memmove.p0i8.p0i8.i64(i8* , i8* , + // i64 , i1 ) + case "@llvm.memmove.p0i8.p0i8.i64" when call.Arguments.Length >= 3: + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); + Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol))); + return; // declare void @llvm.memset.p0i8.i32(i8* , i8 , // i32, i1) case "@llvm.memset.p0i8.i32" when call.Arguments.Length >= 3: @@ -2536,39 +2560,74 @@ void EmitCall(IR.CallInstruction call, Block fromBlock) Emit (il.Create (OpCodes.Conv_U4)); Emit (il.Create (OpCodes.Initblk)); return; - // declare void @llvm.memcpy.p0i8.p0i8.i32(i8* , i8* , - // i32 , i1 ) - case "@llvm.memcpy.p0i8.p0i8.i32" when call.Arguments.Length >= 3: + case "@llvm.pow.f64": EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); - EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); - Emit (il.Create (OpCodes.Cpblk)); + Emit (il.Create (OpCodes.Call, compilation.sysMathPowD)); return; - // declare void @llvm.memcpy.p0i8.p0i8.i64(i8* , i8* , - // i64 , i1 ) - case "@llvm.memcpy.p0i8.p0i8.i64" when call.Arguments.Length >= 3: + case "@llvm.smax.i8": EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); - EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); - Emit (il.Create (OpCodes.Conv_U4)); - Emit (il.Create (OpCodes.Cpblk)); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxSByte)); + return; + case "@llvm.smax.i16": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt16)); + return; + case "@llvm.smax.i32": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt32)); + return; + case "@llvm.smax.i64": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt64)); + return; + case "@llvm.sqrt.f64": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathSqrtD)); + return; + case "@llvm.stackrestore": + compilation.WarningMessage (module.SourceFilename, $"Stack restore is not supported in `{MangledName.Demangle (function.Symbol)}`"); return; - // declare void @llvm.memmove.p0i8.p0i8.i64(i8* , i8* , - // i64 , i1 ) - //case "@llvm.memmove.p0i8.p0i8.i64" when call.Arguments.Length >= 3: - // EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); - // EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); - // EmitValue (call.Arguments[2].Value, call.Arguments[2].Type); - // Emit (il.Create (OpCodes.Conv_U4)); - // Emit (il.Create (OpCodes.Cpblk)); - // return; case "@llvm.stacksave": compilation.WarningMessage (module.SourceFilename, $"Stack save is not supported in `{MangledName.Demangle (function.Symbol)}`"); Emit (il.Create (OpCodes.Ldc_I4_0)); Emit (il.Create (OpCodes.Conv_U)); return; - case "@llvm.stackrestore": - compilation.WarningMessage (module.SourceFilename, $"Stack restore is not supported in `{MangledName.Demangle (function.Symbol)}`"); + case "@llvm.trap": + Emit (il.Create (OpCodes.Ldstr, "Trap")); + Emit (il.Create (OpCodes.Newobj, compilation.sysExceptionCtor)); + Emit (il.Create (OpCodes.Throw)); + return; + case "@llvm.umax.i8": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxByte)); + return; + case "@llvm.umax.i16": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt16)); + return; + case "@llvm.umax.i32": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt32)); + return; + case "@llvm.umax.i64": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxUInt64)); + return; + case "@llvm.usub.sat.i64": + EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); + EmitValue (call.Arguments[1].Value, call.Arguments[1].Type); + Emit (il.Create (OpCodes.Sub)); + Emit (il.Create (OpCodes.Ldc_I8, 0L)); + Emit (il.Create (OpCodes.Call, compilation.sysMathMaxInt64)); return; case "@llvm.va_start": EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); @@ -2579,11 +2638,6 @@ void EmitCall(IR.CallInstruction call, Block fromBlock) EmitValue (call.Arguments[0].Value, call.Arguments[0].Type); Emit (il.Create (OpCodes.Call, compilation.GetSystemMethod (gv.Symbol))); return; - case "@llvm.trap": - Emit (il.Create (OpCodes.Ldstr, "Trap")); - Emit (il.Create (OpCodes.Newobj, compilation.sysExceptionCtor)); - Emit (il.Create (OpCodes.Throw)); - return; default: if (compilation.TryGetFunction (module, gv.Symbol, out var m)) { diff --git a/Makefile b/Makefile index 3f927be..5a60683 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,11 @@ all: Iril/IR/Parser.cs - Iril/IR/Parser.cs: Iril/IR/IR.jay Makefile Lib/skeleton.cs.template ./Lib/jay -c -v Iril/IR/IR.jay < Lib/skeleton.cs.template > $@ +clean: + rm -rf Iril/bin Iril/obj Cli/bin Cli/obj +restore: + dotnet restore \ No newline at end of file diff --git a/StdLib/Llvm.cs b/StdLib/Llvm.cs index 1318e95..7f3b49a 100644 --- a/StdLib/Llvm.cs +++ b/StdLib/Llvm.cs @@ -128,5 +128,40 @@ public unsafe static void va_end (byte* arglist) Memory.UnregisterMemory (list->reg_save_area); } } + + [DllExport ("@llvm.fshl.i64")] + public unsafe static ulong fshl_i64(ulong a, ulong b, ulong c) + { + // Performs a funnel shift left: + // The first two values are concatenated as { %a : %b } + // (%a is the most significant bits of the wide value), + // the combined value is shifted left, + // and the most significant bits are extracted + // to produce a result that is the same size as the original arguments. + var result = a; + while (c > 0) { + result = (result << 1) | (b >> 63); + b <<= 1; + c--; + } + return result; + } + + [DllExport ("@llvm.memmove.p0i8.p0i8.i64")] + public unsafe static void memmove (byte* dest, byte* src, size_t len) + { + byte* d = (byte*)dest; + byte* s = (byte*)src; + byte* r = d; + if (s < d) { + d += len; + s += len; + while (len-- != 0) + *--d = *--s; + } + else + while (len-- != 0) + *d++ = *s++; + } } } diff --git a/StdLib/Memory.cs b/StdLib/Memory.cs index fc5ce6f..07ec261 100644 --- a/StdLib/Memory.cs +++ b/StdLib/Memory.cs @@ -3,11 +3,11 @@ using System; using size_t = System.UInt64; using System.Runtime.InteropServices; -using System.Threading; -using System.Collections.Generic; -using System.Drawing; -using System.Collections; - +using System.Threading; +using System.Collections.Generic; +using System.Drawing; +using System.Collections; + namespace StdLib { [DllExport] @@ -20,7 +20,7 @@ public static class Memory return memmove (dest, src, len); } - static unsafe void* memmove (void* dest, void* src, size_t len) + public static unsafe void* memmove (void* dest, void* src, size_t len) { byte* d = (byte*)dest; byte* s = (byte*)src; @@ -111,21 +111,21 @@ unsafe static int strcmp (byte* s1, byte* s2) //static unsafe readonly MemoryBlock regHead = new MemoryBlock (null, 0, "Root of All Memory"); [DllExport] - unsafe class MemoryBlock - { - public byte* Pointer; - public long Length; - public string Purpose; - - //public MemoryBlock? Less; - //public MemoryBlock? Greater; - - public MemoryBlock (byte* pointer, long length, string purpose) - { - Pointer = pointer; - Length = length; - Purpose = purpose; - } + unsafe class MemoryBlock + { + public byte* Pointer; + public long Length; + public string Purpose; + + //public MemoryBlock? Less; + //public MemoryBlock? Greater; + + public MemoryBlock (byte* pointer, long length, string purpose) + { + Pointer = pointer; + Length = length; + Purpose = purpose; + } } [DllExport ("@strncmp")] @@ -146,125 +146,124 @@ public unsafe static int strncmp (byte* s1, byte* s2, long n) [DllExport ("@_verify_read_pointer")] public unsafe static void VerifyReadPointer (byte* pointer) - { - lock (registeredMemory) { - var n = registeredMemory.Count; - int insertAt = 0; - while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { - insertAt++; - } - var i = insertAt - 1; - if (0 <= i && i < registeredMemory.Count) { - var b = (MemoryBlock)registeredMemory[i]; - var offset = pointer - b.Pointer; - if (offset > b.Length) { - throw new Exception ($"Read Access Violation 0x{(ulong)pointer:x}. Address outside the range of block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); - } - //Console.WriteLine ($"READ 0x{(ulong)pointer:x} block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); - } - else { - throw new Exception ($"Read Access Violation 0x{(ulong)pointer:x}. Could not find allocated block @{i}/{registeredMemory.Count}"); - } - } - - //Console.WriteLine ("READ " + (IntPtr)pointer); - } - + { + lock (registeredMemory) { + var n = registeredMemory.Count; + int insertAt = 0; + while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { + insertAt++; + } + var i = insertAt - 1; + if (0 <= i && i < registeredMemory.Count) { + var b = (MemoryBlock)registeredMemory[i]; + var offset = pointer - b.Pointer; + if (offset > b.Length) { + throw new Exception ($"Read Access Violation 0x{(ulong)pointer:x}. Address outside the range of block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); + } + //Console.WriteLine ($"READ 0x{(ulong)pointer:x} block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); + } + else { + throw new Exception ($"Read Access Violation 0x{(ulong)pointer:x}. Could not find allocated block @{i}/{registeredMemory.Count}"); + } + } + + //Console.WriteLine ("READ " + (IntPtr)pointer); + } + [DllExport ("@_verify_write_pointer")] public unsafe static void VerifyWritePointer (byte* pointer) - { - lock (registeredMemory) { - var n = registeredMemory.Count; - int insertAt = 0; - while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { - insertAt++; - } - var i = insertAt - 1; - if (0 <= i && i < registeredMemory.Count) { - var b = (MemoryBlock)registeredMemory[i]; - var offset = pointer - b.Pointer; - if (offset > b.Length) { - throw new Exception ($"Write Access Violation 0x{(ulong)pointer:x}. Address outside the range of block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); - } - //Console.WriteLine ($"WRITE 0x{(ulong)pointer:x} block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); - } - else { - throw new Exception ($"Write Access Violation 0x{(ulong)pointer:x}. Could not find allocated block @{i}/{registeredMemory.Count}"); - } - } - } - + { + lock (registeredMemory) { + var n = registeredMemory.Count; + int insertAt = 0; + while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { + insertAt++; + } + var i = insertAt - 1; + if (0 <= i && i < registeredMemory.Count) { + var b = (MemoryBlock)registeredMemory[i]; + var offset = pointer - b.Pointer; + if (offset > b.Length) { + throw new Exception ($"Write Access Violation 0x{(ulong)pointer:x}. Address outside the range of block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); + } + //Console.WriteLine ($"WRITE 0x{(ulong)pointer:x} block @{i}/{registeredMemory.Count} {b.Purpose}[{(IntPtr)offset}/{b.Length}]"); + } + else { + throw new Exception ($"Write Access Violation 0x{(ulong)pointer:x}. Could not find allocated block @{i}/{registeredMemory.Count}"); + } + } + } + [DllExport ("@_register_memory")] public unsafe static void RegisterMemory (byte* pointer, long size, string purpose) - { - //var b = new MemoryBlock (pointer, size, purpose); - - // Save it in the list - //lock (regHead) { - // var p = regHead; - - // if (p.Pointer == pointer) { - // throw new Exception ($"Reallocated memory at {new IntPtr(pointer)}"); - // } - // else if (pointer > p.Pointer) { - // if (p.Greater == null) { - - // } - // } - //} - - lock (registeredMemory) { - var n = registeredMemory.Count; - int insertAt = 0; - while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { - insertAt++; - } - registeredMemory.Insert (insertAt, new MemoryBlock (pointer, size, purpose)); - //Console.WriteLine ($"REGISTER @{insertAt} 0x{(ulong)pointer:x} length {size} for {purpose}"); - } - //Console.WriteLine ("REGISTER " + (IntPtr)pointer + " length " + size + " for " + purpose); - } - + { + //var b = new MemoryBlock (pointer, size, purpose); + + // Save it in the list + //lock (regHead) { + // var p = regHead; + + // if (p.Pointer == pointer) { + // throw new Exception ($"Reallocated memory at {new IntPtr(pointer)}"); + // } + // else if (pointer > p.Pointer) { + // if (p.Greater == null) { + + // } + // } + //} + + lock (registeredMemory) { + var n = registeredMemory.Count; + int insertAt = 0; + while (insertAt < n && pointer >= ((MemoryBlock)registeredMemory[insertAt]).Pointer) { + insertAt++; + } + registeredMemory.Insert (insertAt, new MemoryBlock (pointer, size, purpose)); + //Console.WriteLine ($"REGISTER @{insertAt} 0x{(ulong)pointer:x} length {size} for {purpose}"); + } + //Console.WriteLine ("REGISTER " + (IntPtr)pointer + " length " + size + " for " + purpose); + } + [DllExport ("@_unregister_memory")] public unsafe static void UnregisterMemory (byte* pointer) - { - if (pointer == null) - return; - lock (registeredMemory) { - var n = registeredMemory.Count; - int insertAt = 0; - for (var i = 0; i < n; i++) { - var b = ((MemoryBlock)registeredMemory[i]); - if (b.Pointer == pointer) { - //Console.WriteLine ($"UNREGISTER @{insertAt} 0x{(ulong)pointer:x} length {b.Length} for {b.Purpose}"); - registeredMemory.RemoveAt (i); - return; - } - } - throw new Exception ($"Free Access Violation. No block for 0x{(ulong)pointer:x}"); - } - } - + { + if (pointer == null) + return; + lock (registeredMemory) { + var n = registeredMemory.Count; + for (var i = 0; i < n; i++) { + var b = ((MemoryBlock)registeredMemory[i]); + if (b.Pointer == pointer) { + //Console.WriteLine ($"UNREGISTER @{insertAt} 0x{(ulong)pointer:x} length {b.Length} for {b.Purpose}"); + registeredMemory.RemoveAt (i); + return; + } + } + throw new Exception ($"Free Access Violation. No block for 0x{(ulong)pointer:x}"); + } + } + [DllExport ("@malloc")] public unsafe static byte* malloc (long size) - { - var pointer = (byte*)Marshal.AllocHGlobal ((IntPtr)size); - if (Safe) { - RegisterMemory (pointer, size, "malloc"); - } - return pointer; - } - + { + var pointer = (byte*)Marshal.AllocHGlobal ((IntPtr)size); + if (Safe) { + RegisterMemory (pointer, size, "malloc"); + } + return pointer; + } + [DllExport ("@free")] public unsafe static void free (byte* pointer) - { + { Marshal.FreeHGlobal ((IntPtr)pointer); if (Safe) { - UnregisterMemory (pointer); - } + UnregisterMemory (pointer); + } } - - public static bool Safe = true; + + public static bool Safe = true; } public class DllExportAttribute : Attribute