Prexonite, a .NET hosted scripting language with a focus on meta-programming and embedded DSLs
0

Configure Feed

Select the types of activity you want to include in your feed.

add some .net 9 constructs

Christian Klauser (Sep 20, 2025, 5:50 PM +0200) 24e29da9 47933bd2

+949 -618
+14 -2
Prexonite/Application.cs
··· 366 366 /// <param name = "parentEngine">The engine in which execute the entry function.</param> 367 367 /// <param name = "args">The actual arguments for the entry function.</param> 368 368 /// <returns>The value returned by the entry function.</returns> 369 - public PValue Run(Engine parentEngine, PValue[] args) 369 + public PValue Run(Engine parentEngine, ReadOnlySpan<PValue> args) 370 370 { 371 371 string entryName = Meta[EntryKey]; 372 372 if (!Functions.TryGetValue(entryName, out var func)) ··· 377 377 EnsureInitialization(parentEngine); 378 378 379 379 return func.Run(parentEngine, args); 380 + } 381 + 382 + /// <summary> 383 + /// Executes the application's <see cref = "EntryFunction">entry function</see> in the given <paramref 384 + /// name = "parentEngine">Engine</paramref> and returns it's result. 385 + /// </summary> 386 + /// <param name = "parentEngine">The engine in which execute the entry function.</param> 387 + /// <param name = "args">The actual arguments for the entry function.</param> 388 + /// <returns>The value returned by the entry function.</returns> 389 + public PValue Run(Engine parentEngine, params PValue[] args) 390 + { 391 + return Run(parentEngine, args.AsSpan()); 380 392 } 381 393 382 394 /// <summary> ··· 507 519 /// <seealso cref = "EntryKey" /> 508 520 /// <seealso cref = "EntryFunction" /> 509 521 [DebuggerStepThrough] 510 - public PValue IndirectCall(StackContext sctx, PValue[] args) 522 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 511 523 { 512 524 return Run(sctx.ParentEngine, args); 513 525 }
+12 -7
Prexonite/ApplicationCompound.cs
··· 50 50 51 51 #region IObject Members 52 52 53 - bool IObject.TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 54 - [NotNullWhen(true)] out PValue? result) 53 + bool IObject.TryDynamicCall( 54 + StackContext sctx, 55 + ReadOnlySpan<PValue> args, 56 + PCall call, 57 + string id, 58 + [NotNullWhen(true)] 59 + out PValue? result 60 + ) 55 61 { 56 - return TryDynamicCall(sctx, args, call, id, out result); 62 + return tryDynamicCall(sctx, args, call, id, out result); 57 63 } 58 64 59 65 #endregion ··· 71 77 72 78 public abstract bool Contains(ModuleName moduleName); 73 79 74 - protected virtual bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, 80 + bool tryDynamicCall(StackContext sctx, ReadOnlySpan<PValue> args, PCall call, 75 81 string id, [NotNullWhen(true)] out PValue? result) 76 82 { 77 83 switch (id.ToUpperInvariant()) ··· 83 89 PValue target = args[1]; 84 90 if (TryGetApplication(moduleName, out var application)) 85 91 { 86 - target.IndirectCall(sctx, 87 - new[] {sctx.CreateNativePValue(application)}); 92 + target.IndirectCall(sctx, sctx.CreateNativePValue(application)); 88 93 result = true; 89 94 } 90 95 else 91 96 { 92 - target.IndirectCall(sctx, new PValue[] {PType.Null}); 97 + target.IndirectCall(sctx, PType.Null); 93 98 result = false; 94 99 } 95 100 return true;
+2 -2
Prexonite/CilClosure.cs
··· 77 77 /// <param name = "sctx">The stack context in which to invoke the function.</param> 78 78 /// <param name = "args">A list of arguments to pass to the function.</param> 79 79 /// <returns>The value returned by the function.</returns> 80 - public PValue IndirectCall(StackContext sctx, PValue[] args) 80 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 81 81 { 82 82 if (Function.CilImplementation is not {} cilImplementation) 83 83 throw new PrexoniteException("CilClosure cannot handle " + Function + ··· 86 86 var callCtx = sctx.ParentApplication == Function.ParentApplication 87 87 ? sctx 88 88 : CilFunctionContext.New(sctx, Function); 89 - cilImplementation(Function, callCtx, args, SharedVariables, out var result, out _); 89 + cilImplementation(Function, callCtx, args.ToArray(), SharedVariables, out var result, out _); 90 90 return result; 91 91 } 92 92
+2 -2
Prexonite/Closure.cs
··· 73 73 /// <param name = "sctx">The stack context in which to invoke the function.</param> 74 74 /// <param name = "args">A list of arguments to pass to the function.</param> 75 75 /// <returns>The value returned by the function.</returns> 76 - public virtual PValue IndirectCall(StackContext sctx, PValue[] args) 76 + public virtual PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 77 77 { 78 - var fctx = CreateStackContext(sctx, args); 78 + var fctx = CreateStackContext(sctx, args.ToArray()); 79 79 return sctx.ParentEngine.Process(fctx); 80 80 } 81 81
+6 -20
Prexonite/Commands/Concurrency/AsyncSeq.cs
··· 264 264 } 265 265 266 266 //Makes working with select from managed code easier 267 - class PFunc : IIndirectCall 267 + class PFunc(PFuncImpl f) : IIndirectCall 268 268 { 269 - readonly Func<StackContext, PValue[], PValue> _f; 270 - 271 - public PFunc(Func<StackContext, PValue[], PValue> f) 272 - { 273 - _f = f; 274 - } 275 - 276 269 #region Implementation of IIndirectCall 277 270 278 - public PValue IndirectCall(StackContext sctx, PValue[] args) 279 - { 280 - return _f(sctx, args); 281 - } 271 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) => f(sctx, args); 282 272 283 273 #endregion 284 274 285 - public static implicit operator PValue(PFunc f) 286 - { 287 - return PType.Object.CreatePValue(f); 288 - } 275 + public static implicit operator PValue(PFunc f) => PType.Object.CreatePValue(f); 289 276 } 290 277 291 - static PValue pfunc(Func<StackContext, PValue[], PValue> f) 292 - { 293 - return new PFunc(f); 294 - } 278 + static PValue pfunc(PFuncImpl f) => new PFunc(f); 295 279 280 + delegate PValue PFuncImpl(StackContext sctx, ReadOnlySpan<PValue> args); 281 + 296 282 public static PValue RunStatically(StackContext sctx, PValue[] args) 297 283 { 298 284 var carrier = new ContextCarrier();
+2 -2
Prexonite/Commands/Concurrency/CallAsync.cs
··· 49 49 50 50 #region Overrides of PCommand 51 51 52 - public override PValue Run(StackContext sctx, PValue[] args) 52 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 53 53 { 54 - return RunStatically(sctx, args); 54 + return RunStatically(sctx, args.ToArray()); 55 55 } 56 56 57 57 public static PValue RunStatically(StackContext sctx, PValue[]? args)
+1 -1
Prexonite/Commands/Concurrency/Chan.cs
··· 45 45 46 46 #region Overrides of PCommand 47 47 48 - public override PValue Run(StackContext sctx, PValue[] args) 48 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 49 49 { 50 50 return PType.Object.CreatePValue(new Channel()); 51 51 }
+2 -2
Prexonite/Commands/Concurrency/Select.cs
··· 45 45 46 46 #region Overrides of PCommand 47 47 48 - public override PValue Run(StackContext sctx, PValue[] args) 48 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 49 49 { 50 - return RunStatically(sctx, args); 50 + return RunStatically(sctx, args.ToArray()); 51 51 } 52 52 53 53 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/Core/Boxed.cs
··· 42 42 43 43 #region Overrides of PCommand 44 44 45 - public override PValue Run(StackContext sctx, PValue[] args) 45 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 46 46 { 47 - return RunStatically(sctx, args); 47 + return RunStatically(sctx, args.ToArray()); 48 48 } 49 49 50 50 public static PValue RunStatically(StackContext sctx, PValue[] args)
+4 -11
Prexonite/Commands/Core/Call.cs
··· 123 123 /// <param name = "args">A list of the form [ ref f, arg1, arg2, arg3, ..., argn].<br /> 124 124 /// Lists and coroutines are expanded.</param> 125 125 /// <returns>The result returned by <see cref = "IIndirectCall.IndirectCall" /> or PValue Null if no callable object has been passed.</returns> 126 - public override PValue Run(StackContext sctx, PValue[] args) 126 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 127 127 { 128 - return RunStatically(sctx, args); 129 - } 130 - 131 - [DebuggerStepThrough] 132 - public static List<PValue> FlattenArguments(StackContext sctx, PValue[] args) 133 - { 134 - return FlattenArguments(sctx, args, 0); 128 + return RunStatically(sctx, args.ToArray()); 135 129 } 136 130 137 131 /// <summary> ··· 141 135 /// <param name = "args">The raw list of arguments to process.</param> 142 136 /// <param name = "offset">The offset at which to start processing.</param> 143 137 /// <returns>A copy of the argument list with top-level lists expanded.</returns> 144 - public static List<PValue> FlattenArguments(StackContext sctx, PValue[] args, int offset) 138 + public static List<PValue> FlattenArguments(StackContext sctx, ReadOnlySpan<PValue> args, int offset = 0) 145 139 { 146 - args ??= Array.Empty<PValue>(); 147 - var iargs = new List<PValue>(); 140 + var iargs = new List<PValue>(args.Length); 148 141 for (var i = offset; i < args.Length; i++) 149 142 { 150 143 var arg = args[i];
+2 -2
Prexonite/Commands/Core/CallSubPerform.cs
··· 48 48 /// <param name = "sctx">The stack context in which to execut the command.</param> 49 49 /// <param name = "args">The arguments to be passed to the command.</param> 50 50 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 51 - public override PValue Run(StackContext sctx, PValue[] args) 51 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 52 52 { 53 - return RunStatically(sctx, args); 53 + return RunStatically(sctx, args.ToArray()); 54 54 } 55 55 56 56 public static PValue RunStatically(StackContext sctx, PValue[] args)
+3 -8
Prexonite/Commands/Core/Call_Member.cs
··· 72 72 /// <param name = "args">A list of the form [ obj, id, arg1, arg2, arg3, ..., argn].<br /> 73 73 /// Lists and coroutines are expanded.</param> 74 74 /// <returns>The result returned by the member call.</returns> 75 - public override PValue Run(StackContext sctx, PValue[] args) 75 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 76 76 { 77 77 if (sctx == null) 78 78 throw new ArgumentNullException(nameof(sctx)); ··· 94 94 id = args[1].CallToString(sctx); 95 95 } 96 96 97 - 98 - var iargs = new PValue[args.Length - i]; 99 - Array.Copy(args, i, iargs, 0, iargs.Length); 100 - 101 - return Run(sctx, args[0], isSet, id, iargs); 97 + return Run(sctx, args[0], isSet, id, args.Slice(i, args.Length - i)); 102 98 } 103 99 104 100 /// <summary> ··· 127 123 /// Lists and coroutines are expanded.</param> 128 124 /// <returns>The result returned by the member call.</returns> 129 125 /// <exception cref = "ArgumentNullException"><paramref name = "sctx" /> is null.</exception> 130 - public PValue Run(StackContext sctx, PValue? obj, bool isSet, string id, params PValue[] args) 126 + public PValue Run(StackContext sctx, PValue? obj, bool isSet, string id, params ReadOnlySpan<PValue> args) 131 127 { 132 128 if (obj == null) 133 129 return PType.Null.CreatePValue(); 134 130 if (sctx == null) 135 131 throw new ArgumentNullException(nameof(sctx)); 136 - args ??= Array.Empty<PValue>(); 137 132 138 133 var iargs = new List<PValue>(); 139 134 foreach (var arg in args)
+2 -2
Prexonite/Commands/Core/Call_Tail.cs
··· 53 53 /// <param name = "sctx">The stack context in which to execut the command.</param> 54 54 /// <param name = "args">The arguments to be passed to the command.</param> 55 55 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 56 - public override PValue Run(StackContext sctx, PValue[]? args) 56 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 57 57 { 58 58 if (sctx == null) 59 59 throw new ArgumentNullException(nameof(sctx)); ··· 79 79 return Call.CreateStackContext(sctx, args[0], iargs.ToArray()); 80 80 } 81 81 82 - static List<PValue> make_tailcall(StackContext sctx, PValue[] args) 82 + static List<PValue> make_tailcall(StackContext sctx, ReadOnlySpan<PValue> args) 83 83 { 84 84 var iargs = Call.FlattenArguments(sctx, args, 1); 85 85
+1 -1
Prexonite/Commands/Core/Caller.cs
··· 47 47 /// <param name = "sctx">The stack contetx that wishes to find out, who called him.</param> 48 48 /// <param name = "args">Ignored</param> 49 49 /// <returns>Either the stack context of the caller or null encapsulated in a PValue.</returns> 50 - public override PValue Run(StackContext sctx, PValue[] args) 50 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 51 51 { 52 52 return sctx.CreateNativePValue(GetCaller(sctx)); 53 53 }
+2 -2
Prexonite/Commands/Core/Char.cs
··· 75 75 } 76 76 } 77 77 78 - public override PValue Run(StackContext sctx, PValue[] args) 78 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 79 79 { 80 - return RunStatically(sctx, args); 80 + return RunStatically(sctx, args.ToArray()); 81 81 } 82 82 83 83 #region Implementation of ICilCompilerAware
+2 -2
Prexonite/Commands/Core/CompileToCil.cs
··· 64 64 /// <param name = "sctx">The stack context in which to execute the command.</param> 65 65 /// <param name = "args">The arguments to be passed to the command.</param> 66 66 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 67 - public override PValue Run(StackContext sctx, PValue[] args) 67 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 68 68 { 69 - return RunStatically(sctx, args); 69 + return RunStatically(sctx, args.ToArray()); 70 70 } 71 71 72 72 /// <summary>
+3 -3
Prexonite/Commands/Core/Concat.cs
··· 52 52 /// <remarks> 53 53 /// Please note that this method uses a string builder. The addition operator is faster for only two fragments. 54 54 /// </remarks> 55 - public static string ConcatenateString(StackContext sctx, PValue[] args) 55 + public static string ConcatenateString(StackContext sctx, ReadOnlySpan<PValue> args) 56 56 { 57 57 var elements = new string[args.Length]; 58 58 for (var i = 0; i < args.Length; i++) ··· 85 85 /// <param name = "sctx">The context in which to convert the arguments to strings.</param> 86 86 /// <param name = "args">The list of fragments to concatenate.</param> 87 87 /// <returns>A PValue containing the concatenated string.</returns> 88 - public override PValue Run(StackContext sctx, PValue[] args) 88 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 89 89 { 90 - return RunStatically(sctx, args); 90 + return RunStatically(sctx, args.ToArray()); 91 91 } 92 92 93 93 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Core/ConsolePrint.cs
··· 62 62 /// <param name = "sctx">The stack context in which to execut the command.</param> 63 63 /// <param name = "args">The arguments to be passed to the command.</param> 64 64 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 65 - public override PValue Run(StackContext sctx, PValue[] args) 65 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 66 66 { 67 - return RunStatically(sctx, args); 67 + return RunStatically(sctx, args.ToArray()); 68 68 } 69 69 70 70 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Core/ConsolePrintLine.cs
··· 63 63 /// <param name = "sctx">The stack context in which to execut the command.</param> 64 64 /// <param name = "args">The arguments to be passed to the command.</param> 65 65 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 66 - public override PValue Run(StackContext sctx, PValue[] args) 66 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 67 67 { 68 - return RunStatically(sctx, args); 68 + return RunStatically(sctx, args.ToArray()); 69 69 } 70 70 71 71 #region ICilCompilerAware Members
+3 -3
Prexonite/Commands/Core/Const.cs
··· 63 63 _value = value; 64 64 } 65 65 66 - public PValue IndirectCall(StackContext sctx, PValue[] args) 66 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 67 67 { 68 68 return _value; 69 69 } ··· 85 85 return sctx.CreateNativePValue(new Impl(constant)); 86 86 } 87 87 88 - public override PValue Run(StackContext sctx, PValue[] args) 88 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 89 89 { 90 - return RunStatically(sctx, args); 90 + return RunStatically(sctx, args.ToArray()); 91 91 } 92 92 93 93 public CompilationFlags CheckQualification(Instruction ins)
+2 -2
Prexonite/Commands/Core/CreateModuleName.cs
··· 44 44 45 45 public const string Alias = "create_module_name"; 46 46 47 - public override PValue Run(StackContext sctx, PValue[] args) 47 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 48 48 { 49 - return RunStatically(sctx, args); 49 + return RunStatically(sctx, args.ToArray()); 50 50 } 51 51 52 52 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/Core/CreateSourcePosition.cs
··· 44 44 45 45 #endregion 46 46 47 - public override PValue Run(StackContext sctx, PValue[] args) 47 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 48 48 { 49 - return RunStatically(sctx, args); 49 + return RunStatically(sctx, args.ToArray()); 50 50 } 51 51 52 52 public static PValue RunStatically(StackContext sctx, PValue[] args)
+1 -2
Prexonite/Commands/Core/Debug.cs
··· 33 33 /// </summary> 34 34 public class Debug : PCommand 35 35 { 36 - public override PValue Run(StackContext sctx, PValue[] args) 36 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 37 37 { 38 38 if (sctx == null) 39 39 throw new ArgumentNullException(nameof(sctx)); 40 - args ??= Array.Empty<PValue>(); 41 40 if (sctx is not FunctionContext fctx) 42 41 return false; 43 42 var debugging = DebugHook.IsDebuggingEnabled(fctx.Implementation);
+4 -4
Prexonite/Commands/Core/Dispose.cs
··· 57 57 /// <para> 58 58 /// Dispose tries to call the implementation of the IDisposable interface first before issuing dynamic calls.</para> 59 59 /// </remarks> 60 - public override PValue Run(StackContext sctx, PValue[] args) 60 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 61 61 { 62 - return RunStatically(sctx, args); 62 + return RunStatically(sctx, args.ToArray()); 63 63 } 64 64 65 65 /// <summary> ··· 97 97 if (arg.Value is IObject isObj) 98 98 { 99 99 isObj.TryDynamicCall( 100 - sctx, Array.Empty<PValue>(), PCall.Get, DisposeMemberId, out _); 100 + sctx, [], PCall.Get, DisposeMemberId, out _); 101 101 } 102 102 } 103 103 } 104 104 else 105 105 { 106 - arg.TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, DisposeMemberId, out _); 106 + arg.TryDynamicCall(sctx, [], PCall.Get, DisposeMemberId, out _); 107 107 } 108 108 } 109 109
+2 -2
Prexonite/Commands/Core/GetUnscopedAstFactory.cs
··· 83 83 84 84 #endregion 85 85 86 - public override PValue Run(StackContext sctx, PValue[] args) 86 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 87 87 { 88 - return RunStatically(sctx, args); 88 + return RunStatically(sctx, args.ToArray()); 89 89 } 90 90 91 91 static readonly ConcurrentDictionary<ModuleName,UnscopedFactory> _unscopedFactories = new();
+2 -2
Prexonite/Commands/Core/Id.cs
··· 47 47 return args.Length > 0 ? args[0] : PType.Null; 48 48 } 49 49 50 - public override PValue Run(StackContext sctx, PValue[] args) 50 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 51 51 { 52 - return RunStatically(sctx, args); 52 + return RunStatically(sctx, args.ToArray()); 53 53 } 54 54 55 55 public CompilationFlags CheckQualification(Instruction ins)
+2 -2
Prexonite/Commands/Core/LoadAssembly.cs
··· 47 47 /// <param name = "sctx">The stack context in which to load the assembly</param> 48 48 /// <param name = "args">A list of file paths to assemblies.</param> 49 49 /// <returns>Null</returns> 50 - public override PValue Run(StackContext sctx, PValue[] args) 50 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 51 51 { 52 - return RunStatically(sctx, args); 52 + return RunStatically(sctx, args.ToArray()); 53 53 } 54 54 55 55 public static PValue RunStatically(StackContext sctx, PValue[] args)
+1 -1
Prexonite/Commands/Core/Meta.cs
··· 68 68 /// <param name = "sctx">The stack context in which to execut the command.</param> 69 69 /// <param name = "args">The arguments to be passed to the command.</param> 70 70 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 71 - public override PValue Run(StackContext sctx, PValue[]? args) 71 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 72 72 { 73 73 if (sctx == null) 74 74 throw new ArgumentNullException(nameof(sctx));
+1 -1
Prexonite/Commands/Core/Not.cs
··· 8 8 { 9 9 } 10 10 11 - public override PValue Run(StackContext sctx, PValue[] args) 11 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 12 12 { 13 13 foreach (var arg in args) 14 14 {
+1 -1
Prexonite/Commands/Core/Operators/Operators.tt
··· 36 36 37 37 #region PCommand implementation 38 38 39 - public override PValue Run(StackContext sctx, PValue[] args) 39 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 40 40 { 41 41 if(args.Length < <#=argc#>) 42 42 throw new PrexoniteException("The <#=op.PrxName#> operator requires <#=errMsg#>.");
+2 -4
Prexonite/Commands/Core/Pair.cs
··· 47 47 /// <summary> 48 48 /// Turns to arguments into a key-value pair 49 49 /// </summary> 50 - /// <param name = "args">The arguments to pass to this command. Array must contain 2 elements.</param> 51 50 /// <param name = "sctx">Unused.</param> 51 + /// <param name = "args">The arguments to pass to this command. Array must contain 2 elements.</param> 52 52 /// <remarks> 53 53 /// Equivalent to: 54 54 /// <code>function pair(key, value) = key: value;</code> 55 55 /// </remarks> 56 - public override PValue Run(StackContext sctx, PValue[] args) 56 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 57 57 { 58 - args ??= Array.Empty<PValue>(); 59 - 60 58 if (args.Length < 2) 61 59 return PType.Null.CreatePValue(); 62 60 else
+3 -4
Prexonite/Commands/Core/PartialApplication/FlippedFunctionalPartialCall.cs
··· 47 47 _closedArguments = closedArguments; 48 48 } 49 49 50 - public PValue IndirectCall(StackContext sctx, PValue[] args) 50 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 51 51 { 52 52 return _subject.IndirectCall(sctx, _getEffectiveArgs(args)); 53 53 } 54 54 55 - PValue[] _getEffectiveArgs(PValue[] args) 55 + PValue[] _getEffectiveArgs(ReadOnlySpan<PValue> args) 56 56 { 57 57 var effectiveArgs = 58 58 new PValue[System.Math.Max(args.Length, 1) + _closedArguments.Length]; ··· 61 61 else 62 62 effectiveArgs[0] = PType.Null; 63 63 Array.Copy(_closedArguments, 0, effectiveArgs, 1, _closedArguments.Length); 64 - Array.Copy(args, System.Math.Min(1, args.Length), effectiveArgs, 65 - _closedArguments.Length + 1, System.Math.Max(args.Length - 1, 0)); 64 + args[System.Math.Min(1, args.Length)..].CopyTo(effectiveArgs.AsSpan(_closedArguments.Length + 1, System.Math.Max(args.Length - 1, 0))); 66 65 return effectiveArgs; 67 66 } 68 67
+2 -2
Prexonite/Commands/Core/PartialApplication/FlippedFunctionalPartialCallCommand.cs
··· 44 44 45 45 #endregion 46 46 47 - public override PValue Run(StackContext sctx, PValue[] args) 47 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 48 48 { 49 49 if (args.Length < 1) 50 50 return PType.Null; 51 51 52 52 var closed = new PValue[args.Length - 1]; 53 - Array.Copy(args, 1, closed, 0, args.Length - 1); 53 + args[1..].CopyTo(closed.AsSpan(0, args.Length - 1)); 54 54 return sctx.CreateNativePValue(new FlippedFunctionalPartialCall(args[0], closed)); 55 55 } 56 56
+3 -3
Prexonite/Commands/Core/PartialApplication/FunctionalPartialCall.cs
··· 28 28 29 29 public class FunctionalPartialCall(PValue subject, PValue[] arguments) : IMaybeStackAware 30 30 { 31 - public PValue IndirectCall(StackContext sctx, PValue[] args) 31 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 32 32 { 33 33 return subject.IndirectCall(sctx, _getEffectiveArgs(args)); 34 34 } ··· 62 62 return false; 63 63 } 64 64 65 - PValue[] _getEffectiveArgs(PValue[] args) 65 + PValue[] _getEffectiveArgs(ReadOnlySpan<PValue> args) 66 66 { 67 67 var effectiveArgs = new PValue[args.Length + arguments.Length]; 68 68 Array.Copy(arguments, effectiveArgs, arguments.Length); 69 - Array.Copy(args, 0, effectiveArgs, arguments.Length, args.Length); 69 + args.CopyTo(effectiveArgs.AsSpan(arguments.Length, args.Length)); 70 70 return effectiveArgs; 71 71 } 72 72 }
+2 -2
Prexonite/Commands/Core/PartialApplication/FunctionalPartialCallCommand.cs
··· 43 43 44 44 #endregion 45 45 46 - public override PValue Run(StackContext sctx, PValue[] args) 46 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 47 47 { 48 48 if (args.Length < 1) 49 49 return PType.Null; 50 50 51 51 var closed = new PValue[args.Length - 1]; 52 - Array.Copy(args, 1, closed, 0, args.Length - 1); 52 + args[1..].CopyTo(closed.AsSpan(0, args.Length - 1)); 53 53 return sctx.CreateNativePValue(new FunctionalPartialCall(args[0], closed)); 54 54 } 55 55
+4 -3
Prexonite/Commands/Core/PartialApplication/PartialApplicationBase.cs
··· 24 24 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 25 // IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 26 27 + using System.Collections.Immutable; 27 28 using System.Diagnostics; 28 29 29 30 namespace Prexonite.Commands.Core.PartialApplication; ··· 133 134 System.Diagnostics.Debug.Assert(mapping != 0); 134 135 } 135 136 136 - public virtual PValue IndirectCall(StackContext sctx, PValue[] args) 137 + public virtual PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 137 138 { 138 139 _combineArguments(args, out var nonArguments, out var effectiveArguments); 139 140 140 141 return Invoke(sctx, nonArguments, effectiveArguments); 141 142 } 142 143 143 - void _combineArguments(PValue[] args, out PValue[] nonArguments, 144 + void _combineArguments(ReadOnlySpan<PValue> args, out PValue[] nonArguments, 144 145 out PValue[] effectiveArguments) 145 146 { 146 - System.Diagnostics.Debug.Assert(args.All(value => (PValue?)value != null), 147 + System.Diagnostics.Debug.Assert(args.ToImmutableArray().All(value => (PValue?)value != null), 147 148 "Actual (CLI) null references passed to " + 148 149 GetType().Name + ".IndirectCall"); 149 150
+3 -2
Prexonite/Commands/Core/PartialApplication/PartialApplicationCommandBase.cs
··· 215 215 where TRuntimeParam : notnull 216 216 where TCompileParam : notnull 217 217 { 218 - public override PValue Run(StackContext sctx, PValue[] args) 218 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 219 219 { 220 - var arguments = args.AsSpan(); 220 + var allocatedArgs = args.ToArray(); 221 + var arguments = allocatedArgs.AsSpan(); 221 222 var parameter = FilterRuntimeArguments(sctx, ref arguments); 222 223 223 224 var mappingCandidates = new LinkedList<int>();
+4 -5
Prexonite/Commands/Core/PartialApplication/ThenCommand.cs
··· 43 43 44 44 #region Overrides of PCommand 45 45 46 - public override PValue Run(StackContext sctx, PValue[] args) 46 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 47 47 { 48 - return RunStatically(sctx, args); 48 + return RunStatically(sctx, args.ToArray()); 49 49 } 50 50 51 51 public static PValue RunStatically(StackContext sctx, PValue[] args) ··· 87 87 88 88 #region Implementation of IIndirectCall 89 89 90 - public PValue IndirectCall(StackContext sctx, PValue[] args) 90 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 91 91 { 92 - return OuterExpression.IndirectCall(sctx, 93 - new[] {InnerExpression.IndirectCall(sctx, args)}); 92 + return OuterExpression.IndirectCall(sctx, InnerExpression.IndirectCall(sctx, args)); 94 93 } 95 94 96 95 #endregion
+1 -1
Prexonite/Commands/Core/Print.cs
··· 56 56 /// <param name = "sctx">The context in which to convert the arguments to strings.</param> 57 57 /// <param name = "args">The list of arguments to print.</param> 58 58 /// <returns></returns> 59 - public override PValue Run(StackContext sctx, PValue[] args) 59 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 60 60 { 61 61 var s = Concat.ConcatenateString(sctx, args); 62 62 _writer.Write(s);
+1 -1
Prexonite/Commands/Core/PrintLine.cs
··· 56 56 /// <param name = "sctx">The context in which to convert the arguments to strings.</param> 57 57 /// <param name = "args">The list of arguments to print.</param> 58 58 /// <returns></returns> 59 - public override PValue Run(StackContext sctx, PValue[] args) 59 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 60 60 { 61 61 var s = Concat.ConcatenateString(sctx, args); 62 62
+2 -2
Prexonite/Commands/Core/StaticPrint.cs
··· 71 71 /// <param name = "sctx">The stack context in which to execut the command.</param> 72 72 /// <param name = "args">The arguments to be passed to the command.</param> 73 73 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 74 - public override PValue Run(StackContext sctx, PValue[] args) 74 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 75 75 { 76 - return RunStatically(sctx, args); 76 + return RunStatically(sctx, args.ToArray()); 77 77 } 78 78 79 79 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Core/StaticPrintLine.cs
··· 62 62 /// <param name = "sctx">The stack context in which to execut the command.</param> 63 63 /// <param name = "args">The arguments to be passed to the command.</param> 64 64 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 65 - public override PValue Run(StackContext sctx, PValue[] args) 65 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 66 66 { 67 - return RunStatically(sctx, args); 67 + return RunStatically(sctx, args.ToArray()); 68 68 } 69 69 70 70 #region ICilCompilerAware Members
+1 -1
Prexonite/Commands/Core/Unbind.cs
··· 84 84 /// Each of the supplied arguments is processed individually. 85 85 /// </remarks> 86 86 /// <exception cref = "ArgumentNullException">args is null</exception> 87 - public override PValue Run(StackContext sctx, PValue[] args) 87 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 88 88 { 89 89 if (args == null) 90 90 throw new ArgumentNullException(nameof(args));
+2 -2
Prexonite/Commands/CoroutineCommand.cs
··· 36 36 /// <param name = "sctx">The stack context in which to execut the command.</param> 37 37 /// <param name = "args">The arguments to be passed to the command.</param> 38 38 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 39 - public override PValue Run(StackContext sctx, PValue[] args) 39 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 40 40 { 41 41 if (sctx == null) 42 42 throw new ArgumentNullException(nameof(sctx)); ··· 44 44 throw new ArgumentNullException(nameof(args)); 45 45 46 46 var carrier = new ContextCarrier(); 47 - var corctx = new CoroutineContext(sctx, CoroutineRun(carrier, args)); 47 + var corctx = new CoroutineContext(sctx, CoroutineRun(carrier, args.ToArray())); 48 48 carrier.StackContext = corctx; 49 49 return sctx.CreateNativePValue(new Coroutine(corctx)); 50 50 }
+2 -2
Prexonite/Commands/DelegatePCommand.cs
··· 53 53 /// <param name = "sctx">The stack context in which to execute the command.</param> 54 54 /// <param name = "args">The array of arguments to pass to the command.</param> 55 55 /// <returns></returns> 56 - public override PValue Run(StackContext sctx, PValue[] args) 56 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 57 57 { 58 - return Action(sctx, args); 58 + return Action(sctx, args.ToArray()); 59 59 } 60 60 61 61 /// <summary>
+2 -2
Prexonite/Commands/Lazy/AsThunkCommand.cs
··· 46 46 47 47 #region Overrides of PCommand 48 48 49 - public override PValue Run(StackContext sctx, PValue[] args) 49 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 50 50 { 51 - return RunStatically(sctx, args); 51 + return RunStatically(sctx, args.ToArray()); 52 52 } 53 53 54 54 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/Lazy/ForceCommand.cs
··· 43 43 44 44 #region Overrides of PCommand 45 45 46 - public override PValue Run(StackContext sctx, PValue[] args) 46 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 47 47 { 48 - return RunStatically(sctx, args); 48 + return RunStatically(sctx, args.ToArray()); 49 49 } 50 50 51 51 public static PValue RunStatically(StackContext sctx, PValue[] args)
+11 -5
Prexonite/Commands/Lazy/ThunkCommand.cs
··· 41 41 42 42 #endregion 43 43 44 - public override PValue Run(StackContext sctx, PValue[] args) 44 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 45 45 { 46 - return RunStatically(sctx, args); 46 + return RunStatically(sctx, args.ToArray()); 47 47 } 48 48 49 49 // ReSharper disable MemberCanBePrivate.Global ··· 176 176 177 177 public bool IsEvaluated => _value != null; 178 178 179 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 180 - [NotNullWhen(true)] out PValue? result) 179 + public bool TryDynamicCall( 180 + StackContext sctx, 181 + ReadOnlySpan<PValue> args, 182 + PCall call, 183 + string id, 184 + [NotNullWhen(true)] 185 + out PValue? result 186 + ) 181 187 { 182 188 result = null; 183 189 switch (id.ToUpperInvariant()) ··· 271 277 } 272 278 273 279 [SuppressMessage("ReSharper", "AccessToModifiedClosure")] 274 - PValue IIndirectCall.IndirectCall(StackContext sctx, PValue[] args) 280 + PValue IIndirectCall.IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 275 281 { 276 282 CooperativeContext coopCtx = null!; 277 283 coopCtx = new(sctx, f => _cooperativeForce(coopCtx, f))
+2 -2
Prexonite/Commands/List/All.cs
··· 68 68 return (PValue) lst; 69 69 } 70 70 71 - public override PValue Run(StackContext sctx, PValue[] args) 71 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 72 72 { 73 - return RunStatically(sctx, args); 73 + return RunStatically(sctx, args.ToArray()); 74 74 } 75 75 76 76 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/List/Contains.cs
··· 42 42 43 43 #endregion 44 44 45 - public override PValue Run(StackContext sctx, PValue[] args) 45 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 46 46 { 47 - return RunStatically(sctx, args); 47 + return RunStatically(sctx, args.ToArray()); 48 48 } 49 49 50 50 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/List/Count.cs
··· 67 67 return c; 68 68 } 69 69 70 - public override PValue Run(StackContext sctx, PValue[] args) 70 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 71 71 { 72 - return RunStatically(sctx, args); 72 + return RunStatically(sctx, args.ToArray()); 73 73 } 74 74 75 75 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/List/CreateEnumerator.cs
··· 51 51 /// <param name = "sctx">The stack context in which to execut the command.</param> 52 52 /// <param name = "args">The arguments to be passed to the command.</param> 53 53 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 54 - public override PValue Run(StackContext sctx, PValue[] args) 54 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 55 55 { 56 - return RunStatically(sctx, args); 56 + return RunStatically(sctx, args.ToArray()); 57 57 } 58 58 59 59 // ReSharper disable MemberCanBePrivate.Global
+2 -2
Prexonite/Commands/List/Each.cs
··· 40 40 41 41 #endregion 42 42 43 - public override PValue Run(StackContext sctx, PValue[] args) 43 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 44 44 { 45 - return RunStatically(sctx, args); 45 + return RunStatically(sctx, args.ToArray()); 46 46 } 47 47 48 48 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/List/Except.cs
··· 40 40 41 41 #endregion 42 42 43 - public override PValue Run(StackContext sctx, PValue[] args) 43 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 44 44 { 45 - return RunStatically(sctx, args); 45 + return RunStatically(sctx, args.ToArray()); 46 46 } 47 47 48 48 public static PValue RunStatically(StackContext sctx, PValue[] args)
+1 -1
Prexonite/Commands/List/Exists.cs
··· 28 28 29 29 public class Exists : PCommand 30 30 { 31 - public override PValue Run(StackContext sctx, PValue[] args) 31 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 32 32 { 33 33 if (sctx == null) 34 34 throw new ArgumentNullException(nameof(sctx));
+1 -1
Prexonite/Commands/List/FlatMap.cs
··· 39 39 var xs = Map._ToEnumerable(sctx, arg); 40 40 foreach (var x in xs) 41 41 { 42 - var rawYs = f != null ? f.IndirectCall(sctx, new[] {x}) : x; 42 + var rawYs = f != null ? f.IndirectCall(sctx, x) : x; 43 43 var ys = Map._ToEnumerable(sctx, rawYs); 44 44 foreach (var y in ys) 45 45 {
+3 -3
Prexonite/Commands/List/FoldL.cs
··· 61 61 62 62 foreach (var right in source) 63 63 { 64 - left = f.IndirectCall(sctx, new[] {left, right}); 64 + left = f.IndirectCall(sctx, left, right); 65 65 } 66 66 return left; 67 67 } ··· 104 104 return Run(sctx, f, left ?? PType.Null, source); 105 105 } 106 106 107 - public override PValue Run(StackContext sctx, PValue[] args) 107 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 108 108 { 109 - return RunStatically(sctx, args); 109 + return RunStatically(sctx, args.ToArray()); 110 110 } 111 111 112 112 #region ICilCompilerAware Members
+3 -3
Prexonite/Commands/List/FoldR.cs
··· 66 66 67 67 for (var i = lst.Count - 1; i >= 0; i--) 68 68 { 69 - right = f.IndirectCall(sctx, new[] {lst[i], right}); 69 + right = f.IndirectCall(sctx, lst[i], right); 70 70 } 71 71 return right; 72 72 } 73 73 74 - public override PValue Run(StackContext sctx, PValue[] args) 74 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 75 75 { 76 - return RunStatically(sctx, args); 76 + return RunStatically(sctx, args.ToArray()); 77 77 } 78 78 79 79 public static PValue RunStatically(StackContext sctx, PValue[] args)
+1 -1
Prexonite/Commands/List/ForAll.cs
··· 28 28 29 29 public class ForAll : PCommand 30 30 { 31 - public override PValue Run(StackContext sctx, PValue[] args) 31 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 32 32 { 33 33 if (sctx == null) 34 34 throw new ArgumentNullException(nameof(sctx));
+1 -1
Prexonite/Commands/List/GroupBy.cs
··· 54 54 continue; 55 55 foreach (var x in xs) 56 56 { 57 - var fx = f.IndirectCall(sctx, new[] {x}); 57 + var fx = f.IndirectCall(sctx, x); 58 58 if (!groups.ContainsKey(fx)) 59 59 { 60 60 var lst = new List<PValue>();
+2 -2
Prexonite/Commands/List/HeadTail.cs
··· 40 40 41 41 #endregion 42 42 43 - public override PValue Run(StackContext sctx, PValue[] args) 43 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 44 44 { 45 - return RunStatically(sctx, args); 45 + return RunStatically(sctx, args.ToArray()); 46 46 } 47 47 48 48 public static PValue RunStatically(StackContext sctx, PValue[] args)
+2 -2
Prexonite/Commands/List/List.cs
··· 65 65 /// <param name = "sctx">The stack context in which to execut the command.</param> 66 66 /// <param name = "args">The arguments to be passed to the command.</param> 67 67 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 68 - public override PValue Run(StackContext sctx, PValue[] args) 68 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 69 69 { 70 - return RunStatically(sctx, args); 70 + return RunStatically(sctx, args.ToArray()); 71 71 } 72 72 73 73 #region ICilCompilerAware Members
+1 -1
Prexonite/Commands/List/Map.cs
··· 119 119 var sctx = sctxCarrier.StackContext; 120 120 121 121 foreach (var x in source) 122 - yield return f != null ? f.IndirectCall(sctx, new[] {x}) : x; 122 + yield return f != null ? f.IndirectCall(sctx, x) : x; 123 123 } 124 124 125 125 /// <summary>
+2 -2
Prexonite/Commands/List/Sort.cs
··· 52 52 /// <param name = "sctx">The stack context in which the sort is performed.</param> 53 53 /// <param name = "args">A list of sort expressions followed by the list to sort.</param> 54 54 /// <returns>The a sorted copy of the list.</returns> 55 - public override PValue Run(StackContext sctx, PValue[] args) 55 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 56 56 { 57 57 if (sctx == null) 58 58 throw new ArgumentNullException(nameof(sctx)); ··· 76 76 { 77 77 foreach (var f in clauses) 78 78 { 79 - var pdec = f.IndirectCall(sctx, new[] {a, b}); 79 + var pdec = f.IndirectCall(sctx, a, b); 80 80 if (pdec.Type is not IntPType) 81 81 pdec = pdec.ConvertTo(sctx, PType.Int); 82 82 var dec = (int) pdec.Value!;
+2 -2
Prexonite/Commands/List/Sum.cs
··· 40 40 41 41 #endregion 42 42 43 - public override PValue Run(StackContext sctx, PValue[] args) 43 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 44 44 { 45 - return RunStatically(sctx, args); 45 + return RunStatically(sctx, args.ToArray()); 46 46 } 47 47 48 48 public static PValue RunStatically(StackContext sctx, PValue[] args)
+1 -1
Prexonite/Commands/List/TakeWhile.cs
··· 73 73 foreach (var value in set) 74 74 if ( 75 75 (bool) 76 - f.IndirectCall(sctx, new[] {value, i++}).ConvertTo(sctx, PType.Bool, 76 + f.IndirectCall(sctx, value, i++).ConvertTo(sctx, PType.Bool, 77 77 true).Value!) 78 78 yield return value; 79 79 }
+1 -1
Prexonite/Commands/List/Where.cs
··· 81 81 continue; 82 82 foreach (var value in set) 83 83 { 84 - var include = f.IndirectCall(sctx, new[] {value}).ConvertTo(sctx, PType.Bool, 84 + var include = f.IndirectCall(sctx, value).ConvertTo(sctx, PType.Bool, 85 85 true); 86 86 if ((bool) include.Value!) 87 87 yield return value;
+2 -2
Prexonite/Commands/Math/Abs.cs
··· 49 49 /// <param name = "sctx">The stack context in which to execut the command.</param> 50 50 /// <param name = "args">The arguments to be passed to the command.</param> 51 51 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 52 - public override PValue Run(StackContext sctx, PValue[] args) 52 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 53 53 { 54 - return RunStatically(sctx, args); 54 + return RunStatically(sctx, args.ToArray()); 55 55 } 56 56 57 57 /// <summary>
+2 -2
Prexonite/Commands/Math/Ceiling.cs
··· 69 69 return System.Math.Ceiling(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Cos.cs
··· 69 69 return System.Math.Cos(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Exp.cs
··· 69 69 return System.Math.Exp(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Floor.cs
··· 69 69 return System.Math.Floor(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Log.cs
··· 85 85 return System.Math.Log(x); 86 86 } 87 87 88 - public override PValue Run(StackContext sctx, PValue[] args) 88 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 89 89 { 90 - return RunStatically(sctx, args); 90 + return RunStatically(sctx, args.ToArray()); 91 91 } 92 92 93 93 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Max.cs
··· 91 91 /// <param name = "sctx">The stack context in which to execut the command.</param> 92 92 /// <param name = "args">The arguments to be passed to the command.</param> 93 93 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 94 - public override PValue Run(StackContext sctx, PValue[] args) 94 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 95 95 { 96 - return RunStatically(sctx, args); 96 + return RunStatically(sctx, args.ToArray()); 97 97 } 98 98 99 99 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Min.cs
··· 90 90 /// <param name = "sctx">The stack context in which to execut the command.</param> 91 91 /// <param name = "args">The arguments to be passed to the command.</param> 92 92 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 93 - public override PValue Run(StackContext sctx, PValue[] args) 93 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 94 94 { 95 - return RunStatically(sctx, args); 95 + return RunStatically(sctx, args.ToArray()); 96 96 } 97 97 98 98 #region ICilCompilerAware Members
+1 -1
Prexonite/Commands/Math/Pi.cs
··· 47 47 /// <param name = "sctx">The stack context in which to execut the command.</param> 48 48 /// <param name = "args">The arguments to be passed to the command.</param> 49 49 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 50 - public override PValue Run(StackContext sctx, PValue[] args) 50 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 51 51 { 52 52 return System.Math.PI; 53 53 }
+2 -2
Prexonite/Commands/Math/Round.cs
··· 84 84 /// <param name = "sctx">The stack context in which to execut the command.</param> 85 85 /// <param name = "args">The arguments to be passed to the command.</param> 86 86 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 87 - public override PValue Run(StackContext sctx, PValue[] args) 87 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 88 88 { 89 - return RunStatically(sctx, args); 89 + return RunStatically(sctx, args.ToArray()); 90 90 } 91 91 92 92 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Sin.cs
··· 62 62 return RunStatically(arg0, sctx); 63 63 } 64 64 65 - public override PValue Run(StackContext sctx, PValue[] args) 65 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 66 66 { 67 - return RunStatically(sctx, args); 67 + return RunStatically(sctx, args.ToArray()); 68 68 } 69 69 70 70 public static PValue RunStatically(PValue arg0, StackContext sctx)
+2 -2
Prexonite/Commands/Math/Sqrt.cs
··· 69 69 return System.Math.Sqrt(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Math/Tan.cs
··· 69 69 return System.Math.Tan(x); 70 70 } 71 71 72 - public override PValue Run(StackContext sctx, PValue[] args) 72 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 73 73 { 74 - return RunStatically(sctx, args); 74 + return RunStatically(sctx, args.ToArray()); 75 75 } 76 76 77 77 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/NestedPCommand.cs
··· 55 55 /// <param name = "sctx">The stack context in which to execute the command.</param> 56 56 /// <param name = "args">The arguments to pass to the command invocation.</param> 57 57 /// <returns>The value returned by <c><see cref = "Action" />.Run</c>.</returns> 58 - public override PValue Run(StackContext sctx, PValue[] args) 58 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 59 59 { 60 60 return Action.Run(sctx, args); 61 61 } ··· 89 89 /// <remarks> 90 90 /// If your implementation does not return a value, you have to return <c>PType.Null.CreatePValue()</c> and <strong>not</strong> <c>null</c>! 91 91 /// </remarks> 92 - PValue Run(StackContext sctx, PValue[] args); 92 + PValue Run(StackContext sctx, ReadOnlySpan<PValue> args); 93 93 }
+5 -3
Prexonite/Commands/PCommand.cs
··· 37 37 /// <param name = "sctx">The stack context in which to execut the command.</param> 38 38 /// <param name = "args">The arguments to be passed to the command.</param> 39 39 /// <returns>The value returned by the command. Must not be null. (But possibly {null~Null})</returns> 40 - public abstract PValue Run(StackContext sctx, PValue[] args); 40 + public abstract PValue Run(StackContext sctx, ReadOnlySpan<PValue> args); 41 + 42 + public PValue Run(StackContext sctx, params PValue[] args) => Run(sctx, new ReadOnlySpan<PValue>(args)); 41 43 42 44 #region IIndirectCall Members 43 45 44 46 /// <summary> 45 - /// Runs the command. (Calls <see cref = "Run" />) 47 + /// Runs the command. (Calls <see cref = "Run(Prexonite.StackContext,System.ReadOnlySpan{Prexonite.PValue})" />) 46 48 /// </summary> 47 49 /// <param name = "sctx">The stack context in which to call the command.</param> 48 50 /// <param name = "args">The arguments to pass to the command.</param> 49 51 /// <returns>The value returned by the command.</returns> 50 - PValue IIndirectCall.IndirectCall(StackContext sctx, PValue[] args) 52 + PValue IIndirectCall.IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 51 53 { 52 54 return Run(sctx, args) ?? PType.Null.CreatePValue(); 53 55 }
+1 -1
Prexonite/Commands/ReExportNamespaceExportsTopLevel.cs
··· 7 7 8 8 public class ReExportNamespaceExportsTopLevel(Loader loader) : ICommand 9 9 { 10 - public PValue Run(StackContext sctx, PValue[] args) 10 + public PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 11 11 { 12 12 if (args.Length < 1) 13 13 {
+2 -2
Prexonite/Commands/StackAwareCommand.cs
··· 30 30 { 31 31 public abstract StackContext CreateStackContext(StackContext sctx, PValue[] args); 32 32 33 - public override PValue Run(StackContext sctx, PValue[] args) 33 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 34 34 { 35 - var rctx = CreateStackContext(sctx, args); 35 + var rctx = CreateStackContext(sctx, args.ToArray()); 36 36 return sctx.ParentEngine.Process(rctx); 37 37 } 38 38 }
+2 -2
Prexonite/Commands/Text/SetCenterCommand.cs
··· 84 84 return sb.ToString(); 85 85 } 86 86 87 - public override PValue Run(StackContext sctx, PValue[] args) 87 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 88 88 { 89 - return RunStatically(sctx, args); 89 + return RunStatically(sctx, args.ToArray()); 90 90 } 91 91 92 92 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Text/SetLeftCommand.cs
··· 90 90 return SetLeft(w, s, " "); 91 91 } 92 92 93 - public override PValue Run(StackContext sctx, PValue[] args) 93 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 94 94 { 95 - return RunStatically(sctx, args); 95 + return RunStatically(sctx, args.ToArray()); 96 96 } 97 97 98 98 #region ICilCompilerAware Members
+2 -2
Prexonite/Commands/Text/SetRightCommand.cs
··· 90 90 return SetRight(w, s, " "); 91 91 } 92 92 93 - public override PValue Run(StackContext sctx, PValue[] args) 93 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 94 94 { 95 - return RunStatically(sctx, args); 95 + return RunStatically(sctx, args.ToArray()); 96 96 } 97 97 98 98 #region ICilCompilerAware Members
+8 -2
Prexonite/Compiler/AST/ArgumentsProxy.cs
··· 302 302 303 303 #region Implementation of IObject 304 304 305 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 306 - [NotNullWhen(true)] out PValue? result) 305 + public bool TryDynamicCall( 306 + StackContext sctx, 307 + ReadOnlySpan<PValue> args, 308 + PCall call, 309 + string id, 310 + [NotNullWhen(true)] 311 + out PValue? result 312 + ) 307 313 { 308 314 switch (id.ToUpperInvariant()) 309 315 {
+9 -2
Prexonite/Compiler/AST/AstFactoryBase.cs
··· 943 943 944 944 readonly AstFactoryBridge _bridge; 945 945 946 - public PValue IndirectCall(StackContext sctx, PValue[] args) 946 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 947 947 { 948 948 return _bridge.IndirectCall(sctx, args); 949 949 } ··· 952 952 953 953 #region Implementation of IObject 954 954 955 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 955 + public bool TryDynamicCall( 956 + StackContext sctx, 957 + ReadOnlySpan<PValue> args, 958 + PCall call, 959 + string id, 960 + [NotNullWhen(true)] 961 + out PValue? result 962 + ) 956 963 { 957 964 return _bridge.TryDynamicCall(sctx, args, call, id, out result); 958 965 }
+21 -14
Prexonite/Compiler/AST/AstFactoryBridge.cs
··· 45 45 46 46 #region Implementation of IObject 47 47 48 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 48 + public bool TryDynamicCall( 49 + StackContext sctx, 50 + ReadOnlySpan<PValue> args, 51 + PCall call, 52 + string id, 53 + [NotNullWhen(true)] 54 + out PValue? result 55 + ) 49 56 { 50 57 return TryDynamicCall(sctx, args, call, id, out result, out _); 51 58 } 52 59 53 - static bool _require(PValue[] args, ref int index, [NotNullWhen(true)] out PValue? rawValue) 60 + static bool _require(ReadOnlySpan<PValue> args, ref int index, [NotNullWhen(true)] out PValue? rawValue) 54 61 { 55 62 if (index < args.Length) 56 63 { ··· 66 73 } 67 74 } 68 75 69 - static bool _require(StackContext sctx, PValue[] args, ref int index, [NotNullWhen(true)] out IEnumerable<AstExpr>? argSeq) 76 + static bool _require(StackContext sctx, ReadOnlySpan<PValue> args, ref int index, [NotNullWhen(true)] out IEnumerable<AstExpr>? argSeq) 70 77 { 71 78 if(_require(args, ref index, out var raw)) 72 79 { ··· 81 88 } 82 89 } 83 90 84 - static bool _require<T>(StackContext sctx, PValue[] args, ref int index, [NotNullWhen(true)] out T? value) 91 + static bool _require<T>(StackContext sctx, ReadOnlySpan<PValue> args, ref int index, [NotNullWhen(true)] out T? value) 85 92 { 86 93 if (index < args.Length && args[index].TryConvertTo(sctx, false, out value)) 87 94 { ··· 99 106 [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Local")] 100 107 static bool _takeOptional<T>( 101 108 StackContext sctx, 102 - PValue[] args, 109 + ReadOnlySpan<PValue> args, 103 110 ref int index, 104 111 [NotNullWhen(true)] out T? value, 105 112 T? defaultValue = default ··· 118 125 } 119 126 } 120 127 121 - static bool _takeOptional(PValue[] args, ref int index, out PValue rawValue, PValue? defaultValue = null) 128 + static bool _takeOptional(ReadOnlySpan<PValue> args, ref int index, out PValue rawValue, PValue? defaultValue = null) 122 129 { 123 130 if(index < args.Length) 124 131 { ··· 133 140 } 134 141 } 135 142 136 - static bool _takeOptionalList(StackContext sctx, PValue[] args, ref int index, out IEnumerable<AstExpr> expressions) 143 + static bool _takeOptionalList(StackContext sctx, ReadOnlySpan<PValue> args, ref int index, out IEnumerable<AstExpr> expressions) 137 144 { 138 145 if(_takeOptional(args, ref index, out var raw)) 139 146 { ··· 143 150 } 144 151 else 145 152 { 146 - expressions = Enumerable.Empty<AstExpr>(); 153 + expressions = []; 147 154 return false; 148 155 } 149 156 } 150 157 151 158 [PublicAPI] 152 - protected bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result, out string? detailedError) 159 + protected bool TryDynamicCall(StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result, out string? detailedError) 153 160 { 154 161 if (args.Length == 0 || !args[0].TryConvertTo(sctx, false, out ISourcePosition? position)) 155 162 { ··· 647 654 return node != null; 648 655 } 649 656 650 - static AstGetSet _takeOptionalArguments(StackContext sctx, PValue[] args, int i, AstGetSet complex) 657 + static AstGetSet _takeOptionalArguments(StackContext sctx, ReadOnlySpan<PValue> args, int i, AstGetSet complex) 651 658 { 652 659 if (_takeOptionalList(sctx, args, ref i, out var nodeArgs)) 653 660 complex.Arguments.AddRange(nodeArgs); ··· 658 665 659 666 #region Implementation of IIndirectCall 660 667 661 - public PValue IndirectCall(StackContext sctx, PValue[] args) 668 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 662 669 { 663 670 if (args.Length == 0) 664 671 throw new PrexoniteException("AstFactory.() requires at least one argument, the name of the node type to create."); 665 - if (TryDynamicCall(sctx, args.Skip(1).ToArray(), PCall.Get, args[0].CallToString(sctx), out var result, out var detailedError)) 672 + if (TryDynamicCall(sctx, args[1..], PCall.Get, args[0].CallToString(sctx), out var result, out var detailedError)) 666 673 return result; 667 674 else 668 675 { ··· 672 679 } 673 680 } 674 681 675 - static void _throwInvalidCall(IEnumerable<PValue> args, string errorFormat, string detailedError) 682 + static void _throwInvalidCall(ReadOnlySpan<PValue> args, string errorFormat, string detailedError) 676 683 { 677 684 throw new PrexoniteException(string.Format(errorFormat, detailedError, 678 - args.Select(x => x.Type.ToString()).ToListString())); 685 + args.ToArray().Select(x => x.Type.ToString()).ToListString())); 679 686 } 680 687 681 688 #endregion
+7 -2
Prexonite/Compiler/AST/AstNode.cs
··· 130 130 #region Implementation of IObject 131 131 132 132 public virtual bool TryDynamicCall( 133 - StackContext sctx, PValue[] args, PCall call, string id, 134 - [NotNullWhen(true)] out PValue? result) 133 + StackContext sctx, 134 + ReadOnlySpan<PValue> args, 135 + PCall call, 136 + string id, 137 + [NotNullWhen(true)] 138 + out PValue? result 139 + ) 135 140 { 136 141 result = null; 137 142
+10 -15
Prexonite/Compiler/Cil/Compiler.cs
··· 6 6 using System.Reflection; 7 7 using System.Reflection.Emit; 8 8 using JetBrains.Annotations; 9 - using Lokad.ILPack; 10 9 using Prexonite.Commands; 11 10 using Prexonite.Compiler.Build; 12 11 using Prexonite.Modular; ··· 199 198 200 199 #region Store debug implementation 201 200 201 + [PublicAPI] 202 202 public static void StoreDebugImplementation(StackContext sctx) 203 203 { 204 204 StoreDebugImplementation(sctx.ParentApplication, sctx.ParentEngine); 205 205 } 206 206 207 + [PublicAPI] 207 208 public static void StoreDebugImplementation(StackContext sctx, Application app) 208 209 { 209 210 StoreDebugImplementation(app, sctx.ParentEngine); 210 211 } 211 - 212 - static readonly Lazy<AssemblyGenerator> AssemblyGenerator = 213 - new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication); 214 212 215 213 public static void StoreDebugImplementation(Application app, Engine targetEngine) 216 214 { ··· 236 234 237 235 pass.TargetType.CreateType(); 238 236 239 - // .NET Core no longer offers AssemblyBuilder.Save. We use Lokad.ILPack instead. 240 - AssemblyGenerator.Value.GenerateAssembly(pass.Assembly, pass.Assembly.GetName().Name + ".dll"); 237 + pass.Assembly.Save(pass.Assembly.GetName().Name + ".dll"); 241 238 } 242 239 243 240 public static void StoreDebugImplementation(PFunction func, Engine targetEngine) ··· 252 249 _compile(func, il, targetEngine, pass, linking); 253 250 254 251 pass.TargetType.CreateType(); 255 - 256 - //var sm = tb.DefineMethod("whoop", MethodAttributes.Static | MethodAttributes.Public); 257 - 258 - //ab.SetEntryPoint(sm); 259 - AssemblyGenerator.Value.GenerateAssembly(pass.Assembly, pass.Assembly.GetName().Name + ".dll"); 252 + pass.Assembly.Save(pass.Assembly.GetName().Name + ".dll"); 260 253 } 261 254 262 255 public static void StoreDebugImplementation(StackContext sctx, PFunction func) ··· 754 747 state.EmitStorePValue 755 748 ( 756 749 sym, 757 - delegate 750 + () => 758 751 { 759 752 //(idx < argc) ? args[idx] : null; 760 753 state.EmitLdcI4(i); ··· 1779 1772 ?? throw new PrexoniteException("Cannot find method PValue.IsNull(StackContext, PValue)."); 1780 1773 1781 1774 public static MethodInfo PVDynamicCallMethod { get; } = 1782 - typeof(PValue).GetMethod("DynamicCall") 1775 + typeof(PValue).GetMethod("DynamicCall", BindingFlags.Instance | BindingFlags.Public, 1776 + [typeof(StackContext), typeof(PValue[]), typeof(PCall), typeof(string)]) 1783 1777 ?? throw new PrexoniteException("Cannot find method PValue.DynamicCall(StackContext, PValue)."); 1784 1778 1785 1779 public static MethodInfo PVIndirectCallMethod { get; } = 1786 - typeof(PValue).GetMethod("IndirectCall") 1780 + typeof(PValue).GetMethod("IndirectCall", BindingFlags.Instance | BindingFlags.Public, [ 1781 + typeof(StackContext), typeof(PValue[])]) 1787 1782 ?? throw new PrexoniteException("Cannot find method PValue.IndirectCall(StackContext, PValue)."); 1788 1783 1789 1784 public static MethodInfo PVOnesComplementMethod { get; } = 1790 - typeof(PValue).GetMethod("OnesComplement", new[] { typeof(StackContext) }) 1785 + typeof(PValue).GetMethod("OnesComplement", [typeof(StackContext)]) 1791 1786 ?? throw new PrexoniteException("Cannot find method PValue.OnesComplement(StackContext, PValue)."); 1792 1787 1793 1788 // ReSharper restore InconsistentNaming
+35 -4
Prexonite/Compiler/Cil/CompilerPass.cs
··· 28 28 using System.Diagnostics; 29 29 using System.Reflection; 30 30 using System.Reflection.Emit; 31 + using System.Runtime.Loader; 31 32 using Prexonite.Modular; 32 33 33 34 #endregion ··· 47 48 return applicationId + "_" + Interlocked.Increment(ref _numberOfPasses) + ""; 48 49 } 49 50 50 - readonly AssemblyBuilder? _assemblyBuilder; 51 + readonly PersistedAssemblyBuilder? _assemblyBuilder; 51 52 52 - public AssemblyBuilder Assembly 53 + public PersistedAssemblyBuilder Assembly 53 54 { 54 55 [DebuggerStepThrough] 55 56 get ··· 96 97 { 97 98 var sequenceName = _createNextTypeName(app?.Id); 98 99 var asmName = new AssemblyName(sequenceName); 99 - _assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndCollect); 100 + _assemblyBuilder = new PersistedAssemblyBuilder(asmName, typeof(object).Assembly) { 101 + 102 + }; 103 + 100 104 _moduleBuilder = _assemblyBuilder.DefineDynamicModule(asmName.Name!); 101 105 _typeBuilder = _moduleBuilder.DefineType(sequenceName); 102 106 } ··· 270 274 271 275 Type _getRuntimeType() 272 276 { 273 - return _cachedTypeReference ??= TargetType.CreateType(); 277 + if (_cachedTypeReference == null) 278 + { 279 + if (!MakeAvailableForLinking) 280 + { 281 + throw new PrexoniteException("Cannot get CIL implementation type when static linking is not enabled."); 282 + } 283 + 284 + // Emit type IL 285 + _ = TargetType.CreateType(); 286 + 287 + // Unlike the old .NET implementation of Reflection.Emit, we have to decide between 288 + // a persisted and a runtime assembly builder. They are essentially two separate implementations of the 289 + // Reflection.Emit interface. The persisted assembly builder has the drawback that the types it generates 290 + // cannot be used without serializing the IL and loading it as an assembly. 291 + // It's a bit misleading that Microsoft kept the old Reflection.Emit API where `CreateType` returns a "Type". 292 + // That type is secretly still a type builder and can thus not be used with Delegate.CreateDelegate. 293 + using var mem = new MemoryStream(); 294 + _assemblyBuilder.Save(mem); 295 + mem.Seek(0, SeekOrigin.Begin); 296 + var ldCtx = AssemblyLoadContext.GetLoadContext(typeof(CompilerPass).Assembly) 297 + ?? throw new PrexoniteException("Failed to construct assembly load context."); 298 + var loaded = ldCtx.LoadFromStream(mem); 299 + 300 + _cachedTypeReference = loaded.GetType(TargetType.FullName!, throwOnError: true) 301 + ?? throw new PrexoniteException("Generated assembly did not contain the type that holds CIL implementations."); 302 + } 303 + 304 + return _cachedTypeReference; 274 305 } 275 306 276 307 public void LinkMetadata(PFunction func)
+17 -15
Prexonite/Compiler/Cil/CompilerState.cs
··· 402 402 /// <param name = "index">The index of the local variable to load.</param> 403 403 public void EmitLoadLocal(int index) 404 404 { 405 + // TODO: for yet unknown reasons using the short versions of ldloc causes System.Reflection.Emit 406 + // to generate invalid IL (an instruction gets missing after being emitted). 405 407 switch (index) 406 408 { 407 - case 0: 408 - Il.Emit(OpCodes.Ldloc_0); 409 - break; 410 - case 1: 411 - Il.Emit(OpCodes.Ldloc_1); 412 - break; 413 - case 2: 414 - Il.Emit(OpCodes.Ldloc_2); 415 - break; 416 - case 3: 417 - Il.Emit(OpCodes.Ldloc_3); 418 - break; 409 + // case 0: 410 + // Il.Emit(OpCodes.Ldloc_0); 411 + // break; 412 + // case 1: 413 + // Il.Emit(OpCodes.Ldloc_1); 414 + // break; 415 + // case 2: 416 + // Il.Emit(OpCodes.Ldloc_2); 417 + // break; 418 + // case 3: 419 + // Il.Emit(OpCodes.Ldloc_3); 420 + // break; 419 421 default: 420 - if (index < byte.MaxValue) 421 - Il.Emit(OpCodes.Ldloc_S, (byte) index); 422 - else 422 + // if (index < byte.MaxValue) 423 + // Il.Emit(OpCodes.Ldloc_S, (byte) index); 424 + // else 423 425 Il.Emit(OpCodes.Ldloc, index); 424 426 break; 425 427 }
+2 -2
Prexonite/Compiler/Cil/Runtime.cs
··· 287 287 } 288 288 else 289 289 { 290 - return func.Run(sctx.ParentEngine, args); 290 + return func.Run(sctx.ParentEngine, args.AsSpan()); 291 291 } 292 292 } 293 293 ··· 309 309 } 310 310 else 311 311 { 312 - return func.Run(sctx.ParentEngine, args); 312 + return func.Run(sctx.ParentEngine, args.AsSpan()); 313 313 } 314 314 } 315 315
+2 -1
Prexonite/Compiler/CompilerHook.cs
··· 90 90 _managed(target); 91 91 else 92 92 _interpreted.IndirectCall( 93 - target.Loader, new[] {target.Loader.CreateNativePValue(target)}); 93 + target.Loader, 94 + target.Loader.CreateNativePValue(target)); 94 95 } 95 96 finally 96 97 {
+1 -22
Prexonite/Compiler/CompilerTarget.cs
··· 200 200 201 201 #region Implementation of IIndirectCall 202 202 203 - public PValue IndirectCall(StackContext sctx, PValue[] args) 203 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 204 204 { 205 205 return _value; 206 206 } ··· 208 208 #endregion 209 209 } 210 210 211 - class ProvidedFunction : IIndirectCall 212 - { 213 - readonly Func<StackContext, PValue[], PValue> _func; 214 - 215 - public ProvidedFunction(Func<StackContext, PValue[], PValue> func) 216 - { 217 - _func = func; 218 - } 219 - 220 - public PValue IndirectCall(StackContext sctx, PValue[] args) 221 - { 222 - return _func(sctx, args); 223 - } 224 - } 225 - 226 211 /// <summary> 227 212 /// Creates a PVariable object that contains a reference to the supplied value. 228 213 /// </summary> ··· 231 216 public static PVariable CreateReadonlyVariable(PValue value) 232 217 { 233 218 return new() {Value = PType.Object.CreatePValue(new ProvidedValue(value))}; 234 - } 235 - 236 - public static PValue CreateFunctionValue(Func<StackContext, PValue[], PValue> implementation) 237 - { 238 - return new(new ProvidedFunction(implementation), 239 - PType.Object[typeof (IIndirectCall)]); 240 219 } 241 220 242 221 #region Temporary variables
+3 -5
Prexonite/Compiler/CustomResolver.cs
··· 52 52 { 53 53 var presult = _interpreted.IndirectCall 54 54 ( 55 - t.Loader, new[] 56 - { 57 - t.Loader.CreateNativePValue(t), 58 - t.Loader.CreateNativePValue(unresolved), 59 - }); 55 + t.Loader, 56 + t.Loader.CreateNativePValue(t), 57 + t.Loader.CreateNativePValue(unresolved)); 60 58 if (presult.Type is ObjectPType) 61 59 return (AstExpr) presult.Value!; 62 60 else
+1 -1
Prexonite/Compiler/Macro/Commands/CallMacro.cs
··· 66 66 67 67 const int CallingConventionArgumentsCount = 4; 68 68 69 - public override PValue Run(StackContext sctx, PValue[] args) 69 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 70 70 { 71 71 if (args.Length < CallingConventionArgumentsCount) 72 72 throw new PrexoniteException(
+1 -1
Prexonite/Compiler/Macro/Commands/Reference.cs
··· 73 73 74 74 #region Overrides of PCommand 75 75 76 - public override PValue Run(StackContext sctx, PValue[] args) 76 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 77 77 { 78 78 if (args.Length < 3) 79 79 throw new PrexoniteException(string.Format(
+1 -1
Prexonite/Compiler/Macro/Commands/Unpack.cs
··· 96 96 97 97 #region Overrides of PCommand 98 98 99 - public override PValue Run(StackContext sctx, PValue[] args) 99 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 100 100 { 101 101 MacroContext? context; 102 102 if (args.Length < 2 || args[0].Type is not ObjectPType ||
+8 -2
Prexonite/Compiler/Symbolic/Namespace.cs
··· 12 12 public abstract IEnumerator<KeyValuePair<string, Symbol>> GetEnumerator(); 13 13 public abstract bool IsEmpty { get; } 14 14 public abstract bool TryGet(string id, [NotNullWhen(true)] out Symbol? value); 15 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, out PValue result) 15 + public bool TryDynamicCall( 16 + StackContext sctx, 17 + ReadOnlySpan<PValue> args, 18 + PCall call, 19 + string id, 20 + out PValue result 21 + ) 16 22 { 17 23 if ("TRYGET".Equals(id, StringComparison.InvariantCultureIgnoreCase)) 18 24 { ··· 24 30 var found = TryGet(args[0].CallToString(sctx), out var symbol); 25 31 if (args.Length >= 2) 26 32 { 27 - args[1].IndirectCall(sctx, new[] {sctx.CreateNativePValue(symbol)}); 33 + args[1].IndirectCall(sctx, sctx.CreateNativePValue(symbol)); 28 34 } 29 35 30 36 result = sctx.CreateNativePValue(found);
+9 -3
Prexonite/Compiler/Symbolic/Symbol.cs
··· 153 153 } 154 154 public abstract override int GetHashCode(); 155 155 156 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, out PValue result) 156 + public bool TryDynamicCall( 157 + StackContext sctx, 158 + ReadOnlySpan<PValue> args, 159 + PCall call, 160 + string id, 161 + out PValue result 162 + ) 157 163 { 158 - static PValue assignOutParameter(StackContext stackContext, PValue[] innerArgs, object? value, bool found) 164 + static PValue assignOutParameter(StackContext stackContext, ReadOnlySpan<PValue> innerArgs, object? value, bool found) 159 165 { 160 166 if (innerArgs.Length > 0) 161 167 { 162 168 var wrappedValue = found ? stackContext.CreateNativePValue(value) : PType.Null; 163 - innerArgs[0].IndirectCall(stackContext, new[] {wrappedValue}); 169 + innerArgs[0].IndirectCall(stackContext, wrappedValue); 164 170 } 165 171 return stackContext.CreateNativePValue(found); 166 172 }
+8 -2
Prexonite/Compiler/Symbolic/SymbolStore.cs
··· 129 129 130 130 #region Implementation of IObject 131 131 132 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, out PValue result) 132 + public bool TryDynamicCall( 133 + StackContext sctx, 134 + ReadOnlySpan<PValue> args, 135 + PCall call, 136 + string id, 137 + out PValue result 138 + ) 133 139 { 134 140 switch (id.ToUpperInvariant()) 135 141 { ··· 143 149 var symbolic = (string)args[0].ConvertTo(sctx, PType.String, useExplicit: false).Value!; 144 150 if(TryGet(symbolic,out var symbol)) 145 151 { 146 - args[1].IndirectCall(sctx, new[] {sctx.CreateNativePValue(symbol)}); 152 + args[1].IndirectCall(sctx, sctx.CreateNativePValue(symbol)); 147 153 result = true; 148 154 return true; 149 155 }
+10 -4
Prexonite/Concurrency/Channel.cs
··· 32 32 { 33 33 #region Implementation of IObject 34 34 35 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 36 - [NotNullWhen(true)] out PValue? result) 35 + public bool TryDynamicCall( 36 + StackContext sctx, 37 + ReadOnlySpan<PValue> args, 38 + PCall call, 39 + string id, 40 + [NotNullWhen(true)] 41 + out PValue? result 42 + ) 37 43 { 38 44 result = null; 39 45 switch (id.ToUpperInvariant()) ··· 52 58 var refVar = (args.Length > 0 ? args[0] : null) ?? PType.Null; 53 59 if (TryReceive(out var datum)) 54 60 { 55 - refVar.IndirectCall(sctx, new[] {datum}); 61 + refVar.IndirectCall(sctx, datum); 56 62 result = true; 57 63 } 58 64 else 59 65 { 60 - refVar.IndirectCall(sctx, new PValue[] {PType.Null}); 66 + refVar.IndirectCall(sctx, PType.Null); 61 67 result = false; 62 68 } 63 69 break;
+2 -2
Prexonite/Continuation.cs
··· 73 73 return sharedVariables; 74 74 } 75 75 76 - public override PValue IndirectCall(StackContext sctx, PValue[] args) 76 + public override PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 77 77 { 78 78 if (sctx == null) 79 79 throw new ArgumentNullException(nameof(sctx)); 80 80 if (args == null) 81 81 throw new ArgumentNullException(nameof(args)); 82 82 83 - var fctx = CreateFunctionContext(sctx, args); 83 + var fctx = CreateFunctionContext(sctx, args.ToArray()); 84 84 85 85 //run the continuation 86 86 return sctx.ParentEngine.Process(fctx);
+8 -2
Prexonite/Coroutine.cs
··· 120 120 /// <returns>True if a member has been called; false otherwise.</returns> 121 121 [SuppressMessage("ReSharper", "ObjectProducedWithMustDisposeAnnotatedMethodIsNotDisposed")] 122 122 public bool TryDynamicCall( 123 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 123 + StackContext sctx, 124 + ReadOnlySpan<PValue> args, 125 + PCall call, 126 + string id, 127 + [NotNullWhen(true)] 128 + out PValue? result 129 + ) 124 130 { 125 131 switch (id.ToLower()) 126 132 { ··· 160 166 /// This method returns <see cref = "PType.Null" /> PValue if the coroutine is 161 167 /// no longer valid. 162 168 /// </remarks> 163 - public PValue IndirectCall(StackContext sctx, PValue[] args) 169 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 164 170 { 165 171 return Execute(sctx); 166 172 }
+1 -1
Prexonite/Helper/DependencyEntity.cs
··· 45 45 46 46 return value => 47 47 { 48 - var depsPv = getDependenciesPv.IndirectCall(sctx, new[] {value}); 48 + var depsPv = getDependenciesPv.IndirectCall(sctx, value); 49 49 50 50 var depsDynamic = Map._ToEnumerable(sctx, depsPv); 51 51 if (depsDynamic == null)
+39
Prexonite/Helper/Extensions.cs
··· 119 119 } 120 120 121 121 /// <summary> 122 + /// Constructs a human-readable enumeration of the form "x<sub>1</sub>, x<sub>2</sub>, x<sub>3</sub>, …, x<sub>n-2</sub>, x<sub>n-1</sub>, and x<sub>n</sub>". 123 + /// </summary> 124 + /// <typeparam name="T">Any type that supports <see cref="Object.ToString"/>.</typeparam> 125 + /// <param name="source">The enumeration to convert to a string.</param> 126 + /// <returns>A human-readable string.</returns> 127 + public static string? ToEnumerationString<T>(this ReadOnlySpan<T> source) 128 + { 129 + var s = new StringBuilder(); 130 + var hasStarted = false; 131 + string? hold = null; 132 + foreach (var x in source) 133 + { 134 + if (hold != null) 135 + if (hasStarted) 136 + { 137 + s.Append(", "); 138 + s.Append(hold); 139 + } 140 + else 141 + { 142 + s.Append(hold); 143 + hasStarted = true; 144 + } 145 + hold = x?.ToString() ?? ""; 146 + } 147 + 148 + if (hasStarted) 149 + { 150 + s.Append(" and "); 151 + s.Append(hold); 152 + return s.ToString(); 153 + } 154 + else 155 + { 156 + return hold; 157 + } 158 + } 159 + 160 + /// <summary> 122 161 /// Constructs a machine-readable, comma-separated list. ("x<sub>1</sub>, x<sub>2</sub>, …, x<sub>n</sub>"). 123 162 /// </summary> 124 163 /// <typeparam name="T">Any type that supports <see cref="Object.ToString"/>.</typeparam>
+6 -1
Prexonite/IIndirectCall.cs
··· 29 29 /// </para> 30 30 /// </remarks> 31 31 /// <returns>The result of the call. Should <strong>never</strong> be null.</returns> 32 - PValue IndirectCall(StackContext sctx, PValue[] args); 32 + PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args); 33 + } 34 + 35 + public static class IndirectCallExt 36 + { 37 + public static PValue IndirectCall(this IIndirectCall t, StackContext sctx, PValue[] args) => t.IndirectCall(sctx, new ReadOnlySpan<PValue>(args)); 33 38 }
+1
Prexonite/IMaybeStackAware.cs
··· 21 21 bool TryDefer(StackContext sctx, PValue[] args, 22 22 [NotNullWhen(true)] out StackContext? partialApplicationContext, 23 23 [NotNullWhen(false)] out PValue? result); 24 + // TODO ReadOnlySpan this 24 25 }
+19 -6
Prexonite/PFunction.cs
··· 303 303 /// <param name = "sharedVariables">The list of variables shared with the caller.</param> 304 304 /// <returns>The value returned by the function or {null~Null}</returns> 305 305 [PublicAPI] 306 - public PValue Run(Engine engine, PValue[]? args, PVariable[]? sharedVariables) 306 + public PValue Run(Engine engine, ReadOnlySpan<PValue> args, PVariable[]? sharedVariables) 307 307 { 308 + var allocatedArgs = args.ToArray(); 308 309 if (CilImplementation is {} cilImplementation) 309 310 { 310 311 //Fix #8 ··· 313 314 ( 314 315 this, 315 316 new NullContext(engine, ParentApplication, ImportedNamespaces), 316 - args ?? [], 317 + allocatedArgs, 317 318 sharedVariables, 318 319 out var result, out _); 319 320 return result; 320 321 } 321 322 else 322 323 { 323 - var fctx = CreateFunctionContext(engine, args, sharedVariables); 324 + var fctx = CreateFunctionContext(engine, allocatedArgs, sharedVariables); 324 325 engine.Stack.AddLast(fctx); 325 326 return engine.Process(); 326 327 } 328 + } 329 + 330 + [Obsolete("Use the overload that takes a ReadOnlySpan instead.")] 331 + public PValue Run(Engine engine, PValue[] args, PVariable[]? sharedVariables) 332 + { 333 + return Run(engine, args.AsSpan(), sharedVariables); 327 334 } 328 335 329 336 /// <summary> ··· 334 341 /// <returns>A function context for the execution of this function.</returns> 335 342 /// <returns>The value returned by the function or {null~Null}</returns> 336 343 [PublicAPI] 337 - public PValue Run(Engine engine, PValue[]? args) 344 + public PValue Run(Engine engine, ReadOnlySpan<PValue> args) 338 345 { 339 346 return Run(engine, args, null); 340 347 } 341 348 349 + [Obsolete("Use the overload that takes a ReadOnlySpan instead.")] 350 + public PValue Run(Engine engine, PValue[]? args) 351 + { 352 + return Run(engine, args.AsSpan(), null); 353 + } 354 + 342 355 /// <summary> 343 356 /// Executes the function on the supplied engine and returns the result. 344 357 /// </summary> ··· 348 361 [PublicAPI] 349 362 public PValue Run(Engine engine) 350 363 { 351 - return Run(engine, null); 364 + return Run(engine, [], null); 352 365 } 353 366 354 367 #endregion ··· 361 374 /// <param name = "sctx">The stack context from which the function is called.</param> 362 375 /// <param name = "args">The list of arguments to be passed to the function.</param> 363 376 /// <returns>The value returned by the function or {null~Null}</returns> 364 - PValue IIndirectCall.IndirectCall(StackContext sctx, PValue[]? args) 377 + PValue IIndirectCall.IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 365 378 { 366 379 return Run(sctx.ParentEngine, args); 367 380 }
+51 -10
Prexonite/PValue.cs
··· 131 131 /// <returns>The value returned by the dynamic (instance) call. In case the call does not have a return value, a PValue containing null is returned.</returns> 132 132 /// <exception cref = "InvalidCallException">Thrown if the call is not successful.</exception> 133 133 [DebuggerStepThrough] 134 - public PValue DynamicCall(StackContext sctx, PValue[] args, PCall call, string id) 134 + public PValue DynamicCall(StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id) 135 135 { 136 136 return Type.DynamicCall(sctx, this, args, call, id); 137 137 } 138 138 139 + [Obsolete("Use the overload with ReadOnlySpan<PValue> instead.")] 140 + public PValue DynamicCall( 141 + StackContext sctx, 142 + PValue[] args, 143 + PCall call, 144 + string id 145 + ) => DynamicCall(sctx, args.AsSpan(), call, id); 146 + 139 147 /// <summary> 140 148 /// Tries to perform a dynamic (instance) call on the value and stores the result in the out parameter <paramref 141 149 /// name = "result" />. ··· 153 161 /// </remarks> 154 162 [DebuggerStepThrough] 155 163 public bool TryDynamicCall( 156 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 164 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 157 165 { 158 166 return Type.TryDynamicCall(sctx, this, args, call, id, out result); 159 167 } 168 + 169 + /// <summary> 170 + /// Tries to perform a dynamic (instance) call on the value and stores the result in the out parameter <paramref 171 + /// name = "result" />. 172 + /// </summary> 173 + /// <param name = "sctx">The stack context in which to perform the call.</param> 174 + /// <param name = "args">An array of arguments to be passed in the call.</param> 175 + /// <param name = "call">The semantic context of the call. <see cref = "PCall.Get" /> and <see cref = "PCall.Set" /> will have the same effect in most cases. See the TryDynamicCall of <see 176 + /// cref = "PType" /> implementors for details.</param> 177 + /// <param name = "id">The name of the member to call. <paramref name = "id" /> might or might not be case sensitive, depending on the PType. 178 + /// The string can be empty if you want to call the default member (C# only supports default indexers).</param> 179 + /// <param name = "result">Contains the value returned by the dynamic (instance) call. In case the call does not have a return value, a PValue containing null is returned.</param> 180 + /// <returns>True if the call was successful, false otherwise.</returns> 181 + /// <remarks> 182 + /// Note that the value of <paramref name = "result" /> is undefined (and therefor not to be used) if the method call returned false. 183 + /// </remarks> 184 + [DebuggerStepThrough] 185 + [Obsolete("Use the overload with ReadOnlySpan<PValue> instead.")] 186 + public bool TryDynamicCall( 187 + StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) => 188 + TryDynamicCall(sctx, args.AsSpan(), call, id, out result); 160 189 161 190 /// <summary> 162 191 /// Performs a conversion on the value and returns the resulting PValue. You should use <see ··· 377 406 /// Note that the value of <paramref name = "result" /> is undefined (and therefor not to be used) if the method call returned false. 378 407 /// </remarks> 379 408 [DebuggerStepThrough] 380 - public bool TryIndirectCall(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 409 + public bool TryIndirectCall(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 381 410 { 382 411 return Type.IndirectCall(sctx, this, args, out result); 383 412 } ··· 391 420 /// <returns>Contains the value returned by the indirect call. In case the call does not have a return value, a PValue containing null is returned.</returns> 392 421 /// <exception cref = "InvalidCallException">Thrown if the call is not successful.</exception> 393 422 [DebuggerStepThrough] 423 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 424 + { 425 + return Type.IndirectCall(sctx, this, args); 426 + } 427 + 428 + [Obsolete("Use the overload with ReadOnlySpan<PValue> instead.")] 394 429 public PValue IndirectCall(StackContext sctx, PValue[] args) 395 430 { 396 431 return Type.IndirectCall(sctx, this, args); ··· 1395 1430 { 1396 1431 if (Type == PType.String) 1397 1432 return (string) Value!; 1398 - else if (TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, nameof(ToString), out var text)) 1433 + else if (TryDynamicCall(sctx, [], PCall.Get, nameof(ToString), out var text)) 1399 1434 return text.Value!.ToString()!; 1400 1435 else 1401 1436 return ToString(); ··· 1634 1669 #region IObject Members 1635 1670 1636 1671 bool IObject.TryDynamicCall( 1637 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 1672 + StackContext sctx, 1673 + ReadOnlySpan<PValue> args, 1674 + PCall call, 1675 + string id, 1676 + [NotNullWhen(true)] 1677 + out PValue? result 1678 + ) 1638 1679 { 1639 1680 if (Engine.StringsAreEqual(id, "self")) 1640 1681 result = this; ··· 1710 1751 { 1711 1752 result = null; 1712 1753 1713 - if (_tryParseCall(args ?? Array.Empty<object?>(), out var sctx, out var icargs)) 1754 + if (_tryParseCall(args ?? [], out var sctx, out var icargs)) 1714 1755 result = IndirectCall(sctx, icargs); 1715 1756 1716 1757 return result != null || base.TryInvoke(binder, args, out result); ··· 1721 1762 { 1722 1763 result = null; 1723 1764 1724 - if (_tryParseCall(args ?? Array.Empty<object?>(), out var sctx, out var icargs) && 1725 - TryDynamicCall(sctx, icargs, PCall.Get, binder.Name, out var pvresult)) 1765 + if (_tryParseCall(args ?? [], out var sctx, out var icargs) && 1766 + TryDynamicCall(sctx, icargs.AsSpan(), PCall.Get, binder.Name, out var pvresult)) 1726 1767 result = pvresult; 1727 1768 1728 1769 return result != null || base.TryInvokeMember(binder, args, out result); ··· 1733 1774 result = null; 1734 1775 1735 1776 if (_tryParseCall(indexes, out var sctx, out var icargs) && 1736 - TryDynamicCall(sctx, icargs, PCall.Get, string.Empty, out var pvresult)) 1777 + TryDynamicCall(sctx, icargs.AsSpan(), PCall.Get, string.Empty, out var pvresult)) 1737 1778 { 1738 1779 result = pvresult; 1739 1780 } ··· 1748 1789 args[^1] = value; 1749 1790 1750 1791 return _tryParseCall(args, out var sctx, out var icargs) && 1751 - TryDynamicCall(sctx, icargs, PCall.Set, string.Empty, out _) 1792 + TryDynamicCall(sctx, icargs.AsSpan(), PCall.Set, string.Empty, out _) 1752 1793 || base.TrySetIndex(binder, indexes, value); 1753 1794 } 1754 1795
+2 -2
Prexonite/PValueComparer.cs
··· 36 36 return 1; 37 37 else 38 38 { 39 - if (x.TryDynamicCall(_sctx, Array.Empty<PValue>(), PCall.Get, "CompareTo", out var pr)) 39 + if (x.TryDynamicCall(_sctx, [], PCall.Get, "CompareTo", out var pr)) 40 40 { 41 41 if (pr.Type is not IntPType) 42 42 pr.ConvertTo(_sctx, PType.Int); 43 43 return (int) pr.Value!; 44 44 } 45 - else if (y.TryDynamicCall(_sctx, Array.Empty<PValue>(), PCall.Get, "CompareTo", out pr)) 45 + else if (y.TryDynamicCall(_sctx, [], PCall.Get, "CompareTo", out pr)) 46 46 { 47 47 if (pr.Type is not IntPType) 48 48 pr.ConvertTo(_sctx, PType.Int);
+1 -1
Prexonite/PVariable.cs
··· 141 141 /// Otherwise, the first element of <paramref name = "args" /> is assigned to the variable. 142 142 /// </remarks> 143 143 /// <returns>Always the variable's (new) value.</returns> 144 - public PValue IndirectCall(StackContext sctx, PValue[] args) 144 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 145 145 { 146 146 if (args.Length != 0) 147 147 _value = args[^1];
+1 -3
Prexonite/Prexonite.csproj
··· 1 1 <Project Sdk="Microsoft.NET.Sdk"> 2 2 3 3 <PropertyGroup> 4 - <TargetFramework>net8.0</TargetFramework> 4 + <TargetFramework>net9.0</TargetFramework> 5 5 <LangVersion>preview</LangVersion> 6 6 <Nullable>enable</Nullable> 7 7 <ImplicitUsings>enable</ImplicitUsings> ··· 166 166 167 167 <!-- NUGET References --> 168 168 <ItemGroup> 169 - <PackageReference Include="Lokad.ILPack" Version="0.2.0" /> 170 169 <PackageReference Include="PxCoco" Version="1.98.0" /> 171 - <PackageReference Include="System.Reflection.Emit" Version="4.7.0" /> 172 170 <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.13" /> 173 171 </ItemGroup> 174 172 </Project>
+1 -1
Prexonite/StackContext.cs
··· 154 154 /// <param name = "sctx">The stack context in which to execute.</param> 155 155 /// <param name = "args">ignored.</param> 156 156 /// <returns>The value returned by the execution.</returns> 157 - PValue IIndirectCall.IndirectCall(StackContext sctx, PValue[] args) 157 + PValue IIndirectCall.IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 158 158 { 159 159 return sctx.ParentEngine.Process(this); 160 160 }
+5 -4
Prexonite/Types/BoolPType.cs
··· 68 68 69 69 #region Access interface implementation 70 70 71 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 71 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 72 72 { 73 73 if (args.Length <= 0) 74 74 { ··· 84 84 public override bool TryDynamicCall( 85 85 StackContext sctx, 86 86 PValue subject, 87 - PValue[] args, 87 + ReadOnlySpan<PValue> args, 88 88 PCall call, 89 89 string id, 90 - [NotNullWhen(true)] out PValue? result 90 + [NotNullWhen(true)] 91 + out PValue? result 91 92 ) 92 93 { 93 94 //Try CLR dynamic call ··· 96 97 } 97 98 98 99 public override bool TryStaticCall( 99 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 100 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 100 101 { 101 102 if (Object[typeof (bool)].TryStaticCall(sctx, args, call, id, out result)) 102 103 return true;
+6 -7
Prexonite/Types/CharPType.cs
··· 69 69 70 70 #region PType interface 71 71 72 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 72 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 73 73 { 74 74 char c; 75 75 result = null; ··· 103 103 public override bool TryDynamicCall( 104 104 StackContext sctx, 105 105 PValue subject, 106 - PValue[] args, 106 + ReadOnlySpan<PValue> args, 107 107 PCall call, 108 - string? id, 109 - [NotNullWhen(true)] out PValue? result 108 + string id, 109 + [NotNullWhen(true)] 110 + out PValue? result 110 111 ) 111 112 { 112 113 if (sctx == null) 113 114 throw new ArgumentNullException(nameof(sctx)); 114 115 if (subject == null) 115 116 throw new ArgumentNullException(nameof(subject)); 116 - if (args == null) 117 - throw new ArgumentNullException(nameof(args)); 118 117 if (id == null) 119 118 id = ""; 120 119 var c = (char) subject.Value!; ··· 200 199 } 201 200 202 201 public override bool TryStaticCall( 203 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 202 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 204 203 { 205 204 //Try CLR static call 206 205 var clrint = Object[typeof (int)];
+32 -24
Prexonite/Types/ExtendableObject.cs
··· 85 85 /// </para> 86 86 /// <para> 87 87 /// If you want to intercept object member calls yourself, overwrite <see 88 - /// cref = "TryDynamicCall(Prexonite.StackContext,Prexonite.PValue[],Prexonite.Types.PCall,string,out Prexonite.PValue?)" /> instead. 88 + /// cref = "TryDynamicCall(Prexonite.StackContext,System.ReadOnlySpan{Prexonite.PValue},Prexonite.Types.PCall,string,out Prexonite.PValue?)" /> instead. 89 89 /// </para> 90 90 /// </remarks> 91 91 [PublicAPI] 92 92 protected virtual bool TryDynamicClrCall( 93 - StackContext sctx, PValue subject, PValue[] args, PCall call, string id, 93 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, PCall call, string id, 94 94 [NotNullWhen(true)] out PValue? result) 95 95 { 96 96 var objT = subject.Type as ObjectPType; ··· 116 116 /// </para> 117 117 /// <para> 118 118 /// If you want to intercept object member calls yourself, overwrite <see 119 - /// cref = "TryDynamicClrCall(StackContext,PValue,PValue[],PCall,string,out PValue)" /> instead. 119 + /// cref = "TryDynamicClrCall(Prexonite.StackContext,Prexonite.PValue,System.ReadOnlySpan{Prexonite.PValue},Prexonite.Types.PCall,string,out Prexonite.PValue?)" /> instead. 120 120 /// </para> 121 121 /// </remarks> 122 122 [PublicAPI] ··· 142 142 /// </para> 143 143 /// <para> 144 144 /// If you want to intercept object member calls yourself, overwrite <see 145 - /// cref = "TryDynamicClrCall(StackContext,PValue,PValue[],PCall,string,out PValue)" /> instead. 145 + /// cref = "TryDynamicClrCall(Prexonite.StackContext,Prexonite.PValue,System.ReadOnlySpan{Prexonite.PValue},Prexonite.Types.PCall,string,out Prexonite.PValue?)" /> instead. 146 146 /// </para> 147 147 /// </remarks> 148 148 [PublicAPI] 149 149 public bool TryDynamicCall( 150 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 150 + StackContext sctx, 151 + ReadOnlySpan<PValue> args, 152 + PCall call, 153 + string id, 154 + [NotNullWhen(true)] 155 + out PValue? result 156 + ) 151 157 { 152 158 return TryDynamicCall(sctx, sctx.CreateNativePValue(this), args, call, id, out result); 153 159 } ··· 168 174 /// </para> 169 175 /// <para> 170 176 /// If you want to intercept object member calls yourself, overwrite <see 171 - /// cref = "TryDynamicClrCall(StackContext,PValue,PValue[],PCall,string,out PValue)" /> instead. 177 + /// cref = "TryDynamicClrCall(Prexonite.StackContext,Prexonite.PValue,System.ReadOnlySpan{Prexonite.PValue},Prexonite.Types.PCall,string,out Prexonite.PValue?)" /> instead. 172 178 /// </para> 173 179 /// </remarks> 174 180 [PublicAPI] 175 181 public bool TryDynamicCall( 176 - StackContext sctx, PValue subject, PValue[]? args, PCall? call, string? id, 182 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, PCall? call, string? id, 177 183 out PValue? result) 178 184 { 179 185 if (sctx == null) 180 186 throw new ArgumentNullException(nameof(sctx)); 181 - args ??= Array.Empty<PValue>(); 182 187 id ??= ""; 183 188 call ??= PCall.Get; 184 189 ··· 198 203 return result != null; 199 204 } 200 205 206 + [Obsolete("Use TryDynamicCall(StackContext, PValue, ReadOnlySpan<PValue>, PCall?, string?, out PValue?) instead.")] 207 + public bool TryDynamicCall( 208 + StackContext sctx, 209 + PValue subject, 210 + PValue[] args, 211 + PCall? call, 212 + string? id, 213 + out PValue? result 214 + ) => TryDynamicCall(sctx, 215 + subject, 216 + args.AsSpan(), 217 + call, 218 + id, 219 + out result); 220 + 201 221 #endregion 202 222 203 223 [MemberNotNull(nameof(_et))] ··· 240 260 } 241 261 242 262 bool _tryDynamicExtensionCall( 243 - StackContext sctx, PValue subject, PValue[] args, PCall call, string id, 263 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, PCall call, string id, 244 264 [NotNullWhen(true)] 245 265 out PValue? result) 246 266 { ··· 322 342 /// <param name = "sctx">The stack context in which to perform the call.</param> 323 343 /// <param name = "args">The arguments to pass to the handling function.</param> 324 344 /// <returns>The value returned by the extended part of the object.</returns> 325 - public virtual PValue IndirectCall(StackContext sctx, PValue[] args) 326 - { 327 - return IndirectCall(sctx, sctx.CreateNativePValue(this), args); 328 - } 329 - 330 - /// <summary> 331 - /// Indirectly calls the extended part of this object using a different subject (used together with object facades). 332 - /// </summary> 333 - /// <param name = "sctx">The stack context in which to perform the call.</param> 334 - /// <param name = "subject">The subject to substitute for this.</param> 335 - /// <param name = "args">The arguments to pass to the handling function.</param> 336 - /// <returns>The value returned by the extended part of the object.</returns> 337 - public PValue IndirectCall(StackContext sctx, PValue subject, PValue[]? args) 345 + public virtual PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 338 346 { 347 + var subject = sctx.CreateNativePValue(this); 339 348 if (sctx == null) 340 349 throw new ArgumentNullException(nameof(sctx)); 341 - args ??= Array.Empty<PValue>(); 342 350 343 - _et ??= new(); 351 + _et ??= []; 344 352 345 353 if (!_et.TryGetValue(StructurePType.IndirectCallId, out var m)) 346 354 throw new PrexoniteException(this + " does not support indirect calls.");
+7 -6
Prexonite/Types/HashPType.cs
··· 61 61 } 62 62 63 63 public override bool IndirectCall( 64 - StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 64 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 65 65 { 66 66 if (sctx == null) 67 67 throw new ArgumentNullException(nameof(sctx)); ··· 97 97 public override bool TryDynamicCall( 98 98 StackContext sctx, 99 99 PValue subject, 100 - PValue[] args, 100 + ReadOnlySpan<PValue> args, 101 101 PCall call, 102 102 string id, 103 - [NotNullWhen(true)] out PValue? result 103 + [NotNullWhen(true)] 104 + out PValue? result 104 105 ) 105 106 { 106 107 if (sctx == null) ··· 264 265 { 265 266 if (pvht.TryGetValue(args[0], out var value)) 266 267 { 267 - args[1].IndirectCall(sctx, new[] {value}); 268 + args[1].IndirectCall(sctx, value); 268 269 result = true; 269 270 } 270 271 else ··· 287 288 } 288 289 289 290 public override bool TryStaticCall( 290 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 291 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 291 292 { 292 293 if (sctx == null) 293 294 throw new ArgumentNullException(nameof(sctx)); ··· 328 329 return true; 329 330 } 330 331 331 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 332 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 332 333 { 333 334 if (sctx == null) 334 335 throw new ArgumentNullException(nameof(sctx));
+9 -1
Prexonite/Types/IObject.cs
··· 30 30 public interface IObject 31 31 { 32 32 bool TryDynamicCall( 33 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result); 33 + StackContext sctx, 34 + ReadOnlySpan<PValue> args, 35 + PCall call, 36 + string id, 37 + [NotNullWhen(true)] 38 + out PValue? result 39 + ); 40 + 41 + // TODO add backwards compat overload 34 42 }
+5 -4
Prexonite/Types/IntPType.cs
··· 80 80 81 81 #endregion 82 82 83 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 83 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 84 84 { 85 85 if (args.Length < 1) 86 86 { ··· 96 96 public override bool TryDynamicCall( 97 97 StackContext sctx, 98 98 PValue subject, 99 - PValue[] args, 99 + ReadOnlySpan<PValue> args, 100 100 PCall call, 101 101 string id, 102 - [NotNullWhen(true)] out PValue? result 102 + [NotNullWhen(true)] 103 + out PValue? result 103 104 ) 104 105 { 105 106 if (sctx == null) ··· 141 142 } 142 143 143 144 public override bool TryStaticCall( 144 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 145 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 145 146 { 146 147 //Try CLR static call 147 148 var clrint = Object[typeof (int)];
+26 -10
Prexonite/Types/ListPType.cs
··· 26 26 #region 27 27 28 28 using System.Collections; 29 + using System.Collections.Immutable; 29 30 using System.Collections.ObjectModel; 30 31 using System.Reflection; 31 32 using System.Text; ··· 72 73 public override bool TryDynamicCall( 73 74 StackContext sctx, 74 75 PValue subject, 75 - PValue[] args, 76 + ReadOnlySpan<PValue> args, 76 77 PCall call, 77 78 string id, 78 - [NotNullWhen(true)] out PValue? result 79 + [NotNullWhen(true)] 80 + out PValue? result 79 81 ) 80 82 { 81 83 result = null; ··· 246 248 } 247 249 //else 248 250 //Comparison using lambda expressions 251 + var allocatedArgs = args.ToImmutableArray(); 249 252 lst.Sort( 250 - delegate(PValue a, PValue b) 253 + (a, b) => 251 254 { 252 - foreach (var f in args) 255 + foreach (var f in allocatedArgs) 253 256 { 254 - var pdec = f.IndirectCall(sctx, new[] { a, b }); 257 + var pdec = f.IndirectCall(sctx, a, b); 255 258 if (pdec.Type is not IntPType) 256 259 pdec = pdec.ConvertTo(sctx, Int); 257 260 var dec = (int)pdec.Value!; 258 261 if (dec != 0) 259 262 return dec; 260 263 } 264 + 261 265 return 0; 262 266 }); 263 267 result = Null.CreatePValue(); ··· 331 335 } 332 336 333 337 public override bool TryStaticCall( 334 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 338 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 335 339 { 336 340 result = null; 337 341 338 342 if (Engine.StringsAreEqual(id, "Create")) 339 343 { 340 - result = new(new List<PValue>(args), this); 344 + var buf = new List<PValue>(args.Length); 345 + foreach (var arg in args) 346 + { 347 + buf.Add(arg); 348 + } 349 + 350 + result = new(buf, this); 341 351 } 342 352 else if (Engine.StringsAreEqual(id, "CreateFromSize") && args.Length >= 1) 343 353 { ··· 364 374 return result != null; 365 375 } 366 376 367 - public override bool TryConstruct(StackContext sctx, PValue[] args, out PValue result) 377 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, out PValue result) 368 378 { 369 - result = new(new List<PValue>(args), this); 379 + var buf = new List<PValue>(args.Length); 380 + foreach (var arg in args) 381 + { 382 + buf.Add(arg); 383 + } 384 + 385 + result = new(buf, this); 370 386 return true; 371 387 } 372 388 ··· 490 506 } 491 507 492 508 public override bool IndirectCall( 493 - StackContext sctx, PValue subject, PValue[] args, out PValue result) 509 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, out PValue result) 494 510 { 495 511 var lst = new List<PValue>(); 496 512 result = List.CreatePValue(lst);
+6 -5
Prexonite/Types/NullPType.cs
··· 92 92 return Null.CreatePValue(); 93 93 } 94 94 95 - public override bool TryConstruct(StackContext sctx, PValue[] args, out PValue result) 95 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, out PValue result) 96 96 { 97 97 result = Null.CreatePValue(); 98 98 return true; ··· 102 102 public override bool TryDynamicCall( 103 103 StackContext sctx, 104 104 PValue subject, 105 - PValue[] args, 105 + ReadOnlySpan<PValue> args, 106 106 PCall call, 107 107 string id, 108 - [NotNullWhen(true)] out PValue? result 108 + [NotNullWhen(true)] 109 + out PValue? result 109 110 ) 110 111 { 111 112 result = null; ··· 119 120 } 120 121 121 122 public override bool TryStaticCall( 122 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 123 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 123 124 { 124 125 result = null; 125 126 return false; ··· 383 384 /// <returns>Always true (doing nothing can't possibly fail...)</returns> 384 385 [DebuggerStepThrough] 385 386 public override bool IndirectCall( 386 - StackContext sctx, PValue subject, PValue[] args, out PValue result) 387 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, out PValue result) 387 388 { 388 389 //Does nothing 389 390 result = CreatePValue();
+33 -27
Prexonite/Types/ObjectPType.cs
··· 150 150 public override bool TryDynamicCall( 151 151 StackContext sctx, 152 152 PValue subject, 153 - PValue[] args, 153 + ReadOnlySpan<PValue> args, 154 154 PCall call, 155 155 string id, 156 - [NotNullWhen(true)] out PValue? result 156 + [NotNullWhen(true)] 157 + out PValue? result 157 158 ) 158 159 { 159 160 return tryDynamicCall(sctx, subject, args, call, id, out result, out var dummy); ··· 162 163 bool tryDynamicCall( 163 164 StackContext sctx, 164 165 PValue subject, 165 - PValue[] args, 166 + ReadOnlySpan<PValue> args, 166 167 PCall call, 167 168 string id, 168 169 [NotNullWhen(true)] out PValue? result, ··· 175 176 internal bool TryDynamicCall( 176 177 StackContext sctx, 177 178 PValue subject, 178 - PValue[] args, 179 + ReadOnlySpan<PValue> args, 179 180 PCall call, 180 181 string? id, 181 182 [NotNullWhen(true)] out PValue? result, ··· 218 219 return true; 219 220 } 220 221 221 - var cond = new CallConditions(sctx, args, call, id); 222 + var cond = new CallConditions(sctx, args.ToImmutableArray().AsMemory(), call, id); 222 223 MemberTypes mtypes; 223 224 MemberFilter filter; 224 225 if (id.Length != 0) ··· 242 243 ClrType.FindMembers( 243 244 MemberTypes.Method, 244 245 BindingFlags.Public | BindingFlags.Instance, 245 - Type.FilterName, 246 + Type.FilterNameIgnoreCase, 246 247 cond.Call == PCall.Get ? "GetValue" : "SetValue")); 247 248 cond.MemberRestriction.AddRange( 248 249 ClrType.FindMembers( 249 250 MemberTypes.Method, 250 251 BindingFlags.Public | BindingFlags.Instance, 251 - Type.FilterName, 252 + Type.FilterNameIgnoreCase, 252 253 cond.Call == PCall.Get ? "Get" : "Set")); 253 254 } 254 255 } ··· 275 276 276 277 public override bool TryStaticCall( 277 278 StackContext sctx, 278 - PValue[] args, 279 + ReadOnlySpan<PValue> args, 279 280 PCall call, 280 281 string id, 281 282 [NotNullWhen(true)] out PValue? result) ··· 285 286 286 287 bool tryStaticCall( 287 288 StackContext sctx, 288 - PValue[] args, 289 + ReadOnlySpan<PValue> args, 289 290 PCall call, 290 291 string id, 291 292 [NotNullWhen(true)] out PValue? result, ··· 297 298 result = null; 298 299 resolvedMember = null; 299 300 300 - var cond = new CallConditions(sctx, args, call, id); 301 + var cond = new CallConditions(sctx, args.ToImmutableArray().AsMemory(), call, id); 301 302 MemberTypes mtypes; 302 303 MemberFilter filter; 303 304 if (id.Length != 0) ··· 492 493 case MemberTypes.Method: 493 494 var method = (MethodBase) candidate; 494 495 var parameters = method.GetParameters(); 495 - var cargs = new object[parameters.Length]; 496 496 //The Sctx hack needs to modify the supplied arguments, so we need a copy of the original reference 497 497 var sargs = cond.Args; 498 498 var numUpcasts = 0; 499 499 var numConversions = 0; 500 500 501 501 var sctxHackOffset = _sctx_hack(parameters, cond) ? 1 : 0; 502 - for (var i = 0; i < cargs.Length && i + sctxHackOffset < parameters.Length; i++) 502 + for (var i = 0; i < parameters.Length && i + sctxHackOffset < parameters.Length; i++) 503 503 { 504 - var arg = sargs[i]; 504 + var arg = sargs.Span[i]; 505 505 if (arg.IsNull) 506 506 { 507 507 // null matches anything without penalty ··· 553 553 if (_sctx_hack(parameters, cond)) 554 554 { 555 555 //Add cond.Sctx to the array of arguments 556 - sargs = new PValue[sargs.Length + 1]; 557 - Array.Copy(cond.Args, 0, sargs, 1, cond.Args.Length); 558 - sargs[0] = Object.CreatePValue(cond.Sctx); 556 + var a = new PValue[sargs.Length + 1]; 557 + cond.Args.Span.CopyTo(a.AsSpan(1, cond.Args.Length)); 558 + a[0] = Object.CreatePValue(cond.Sctx); 559 + sargs = new(a); 559 560 } 560 561 561 562 for (var i = 0; i < cargs.Length; i++) 562 563 { 563 - var arg = sargs[i]; 564 + var arg = sargs.Span[i]; 564 565 if (!arg.IsNull) //Neither Type-locked nor null 565 566 { 566 567 var pTy = parameters[i].ParameterType; ··· 604 605 result = field.GetValue(subject?.Value); 605 606 else 606 607 { 607 - var arg = cond.Args[0]; 608 + var arg = cond.Args.Span[0]; 608 609 if (!(arg.IsNull)) //Neither Type-locked nor null 609 610 { 610 611 var paramTy = field.FieldType; ··· 706 707 class CallConditions 707 708 { 708 709 public readonly StackContext Sctx; 709 - public readonly PValue[] Args; 710 + public readonly ReadOnlyMemory<PValue> Args; 710 711 public readonly PCall Call; 711 712 public readonly string Id; 712 713 public bool IgnoreId; ··· 714 715 public Type? ReturnType; 715 716 public List<MemberInfo>? MemberRestriction; 716 717 717 - public CallConditions(StackContext sctx, PValue[]? args, PCall call, string id) 718 + public CallConditions(StackContext sctx, ReadOnlyMemory<PValue> args, PCall call, string id) 718 719 { 719 720 Sctx = sctx ?? throw new ArgumentNullException(nameof(sctx)); 720 - Args = args ?? Array.Empty<PValue>(); 721 + Args = args; 721 722 Call = call; 722 723 Id = id; 723 724 Directive = null; ··· 864 865 } 865 866 866 867 public override bool IndirectCall( 867 - StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 868 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 868 869 { 869 870 result = null; 870 871 if (subject.Value is IIndirectCall icall) ··· 880 881 PValue dynamicCall( 881 882 StackContext sctx, 882 883 PValue subject, 883 - PValue[] args, 884 + ReadOnlySpan<PValue> args, 884 885 PCall call, 885 886 string id, 886 887 out MemberInfo? resolvedMember) ··· 907 908 } 908 909 909 910 public override PValue DynamicCall( 910 - StackContext sctx, PValue subject, PValue[] args, PCall call, string id) 911 + StackContext sctx, 912 + PValue subject, 913 + ReadOnlySpan<PValue> args, 914 + PCall call, 915 + string id 916 + ) 911 917 { 912 918 return dynamicCall(sctx, subject, args, call, id, out var dummy); 913 919 } ··· 941 947 return StaticCall(sctx, args, call, id, out var dummy); 942 948 } 943 949 944 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 950 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 945 951 { 946 952 return tryConstruct(sctx, args, out result); 947 953 } 948 954 949 955 bool tryConstruct( 950 - StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 956 + StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 951 957 { 952 - var cond = new CallConditions(sctx, args, PCall.Get, "") 958 + var cond = new CallConditions(sctx, args.ToImmutableArray().AsMemory(), PCall.Get, "") 953 959 { 954 960 IgnoreId = true, 955 961 };
+30 -12
Prexonite/Types/PType.cs
··· 364 364 public abstract bool TryDynamicCall( 365 365 StackContext sctx, 366 366 PValue subject, 367 - PValue[] args, 367 + ReadOnlySpan<PValue> args, 368 368 PCall call, 369 369 string id, 370 - [NotNullWhen(true)] out PValue? result 370 + [NotNullWhen(true)] 371 + out PValue? result 371 372 ); 372 373 373 374 public abstract bool TryStaticCall( 374 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result); 375 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result); 376 + // TODO overload with PValue[] args 375 377 376 - public abstract bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result); 378 + public abstract bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result); 379 + // TODO overload with PValue[] args 377 380 378 381 [DebuggerStepThrough] 379 382 public virtual PValue Construct(StackContext sctx, PValue[] args) ··· 401 404 #region Indirect Call 402 405 403 406 public virtual bool IndirectCall( 404 - StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 407 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 405 408 { 406 409 result = null; 407 410 return false; 408 411 } 409 412 410 - public PValue IndirectCall(StackContext sctx, PValue subject, PValue[] args) 413 + public bool IndirectCall( 414 + StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 415 + { 416 + return IndirectCall(sctx, subject, new ReadOnlySpan<PValue>(args), out result); 417 + } 418 + 419 + public PValue IndirectCall(StackContext sctx, PValue subject, ReadOnlySpan<PValue> args) 411 420 { 412 421 if (IndirectCall(sctx, subject, args, out var ret)) 413 422 return ret; ··· 773 782 #endregion //Operators 774 783 775 784 public virtual PValue DynamicCall( 776 - StackContext sctx, PValue subject, PValue[] args, PCall call, string id) 785 + StackContext sctx, 786 + PValue subject, 787 + ReadOnlySpan<PValue> args, 788 + PCall call, 789 + string id 790 + ) 777 791 { 778 792 if (TryDynamicCall(sctx, subject, args, call, id, out var result)) 779 793 return result; ··· 1259 1273 } 1260 1274 1261 1275 1262 - bool IObject.TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 1263 - [NotNullWhen(true)] out PValue? result) 1276 + bool IObject.TryDynamicCall( 1277 + StackContext sctx, 1278 + ReadOnlySpan<PValue> args, 1279 + PCall call, 1280 + string id, 1281 + [NotNullWhen(true)] 1282 + out PValue? result 1283 + ) 1264 1284 { 1265 1285 result = null; 1266 1286 ··· 1273 1293 else if (Engine.StringsAreEqual(id, StaticCallFromStackId)) 1274 1294 { 1275 1295 //Try perform static call using the first arguments as the member id. 1276 - var actualArgs = new PValue[args.Length - 1]; 1277 - Array.Copy(args, 1, actualArgs, 0, actualArgs.Length); 1278 1296 var actualId = args[0].CallToString(sctx); 1279 - if (!TryStaticCall(sctx, actualArgs, call, actualId, out result)) 1297 + if (!TryStaticCall(sctx, args[1..], call, actualId, out result)) 1280 1298 result = null; 1281 1299 } 1282 1300
+7 -1
Prexonite/Types/PValueEnumerator.cs
··· 83 83 /// Since none of the instance members take any arguments, <paramref name = "args" /> must have length 0. 84 84 /// </remarks> 85 85 public bool TryDynamicCall( 86 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 86 + StackContext sctx, 87 + ReadOnlySpan<PValue> args, 88 + PCall call, 89 + string id, 90 + [NotNullWhen(true)] 91 + out PValue? result 92 + ) 87 93 { 88 94 result = null; 89 95 if (args == null)
+7 -3
Prexonite/Types/PValueKeyValuePair.cs
··· 86 86 /// </remarks> 87 87 /// <exception cref = "ArgumentNullException"><paramref name = "sctx" /> is null.</exception> 88 88 public bool TryDynamicCall( 89 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 89 + StackContext sctx, 90 + ReadOnlySpan<PValue> args, 91 + PCall call, 92 + string id, 93 + [NotNullWhen(true)] 94 + out PValue? result 95 + ) 90 96 { 91 97 if (sctx == null) 92 98 throw new ArgumentNullException(nameof(sctx)); 93 - if (args == null) 94 - throw new ArgumentNullException(nameof(args)); 95 99 if (id == null) 96 100 throw new ArgumentNullException(nameof(id)); 97 101
+5 -4
Prexonite/Types/RealPType.cs
··· 66 66 67 67 #region Access interface implementation 68 68 69 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 69 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 70 70 { 71 71 if (args.Length <= 1) 72 72 { ··· 79 79 public override bool TryDynamicCall( 80 80 StackContext sctx, 81 81 PValue subject, 82 - PValue[] args, 82 + ReadOnlySpan<PValue> args, 83 83 PCall call, 84 84 string id, 85 - [NotNullWhen(true)] out PValue? result 85 + [NotNullWhen(true)] 86 + out PValue? result 86 87 ) 87 88 { 88 89 if (Engine.StringsAreEqual(id, nameof(ToString)) && args.Length == 0) ··· 95 96 } 96 97 97 98 public override bool TryStaticCall( 98 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 99 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 99 100 { 100 101 Object[typeof (double)].TryStaticCall(sctx, args, call, id, out result); 101 102
+8 -7
Prexonite/Types/StringPType.cs
··· 393 393 394 394 #endregion 395 395 396 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 396 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 397 397 { 398 398 result = null; 399 399 if (args.Length <= 0) ··· 408 408 public override bool TryDynamicCall( 409 409 StackContext sctx, 410 410 PValue subject, 411 - PValue[] args, 411 + ReadOnlySpan<PValue> args, 412 412 PCall call, 413 413 string id, 414 - [NotNullWhen(true)] out PValue? result 414 + [NotNullWhen(true)] 415 + out PValue? result 415 416 ) 416 417 { 417 418 result = null; ··· 552 553 553 554 static void _resolve_params( 554 555 StackContext sctx, 555 - IEnumerable<PValue> args, 556 + ReadOnlySpan<PValue> args, 556 557 ref bool isParams, 557 558 ICollection<char> sch, 558 559 ref List<string>? sst, ··· 606 607 } 607 608 608 609 public override bool TryStaticCall( 609 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 610 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 610 611 { 611 612 if (args.Length >= 1 && Engine.StringsAreEqual(id, "unescape")) 612 613 { ··· 631 632 } 632 633 633 634 public override bool IndirectCall( 634 - StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 635 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 635 636 { 636 637 result = null; 637 638 var str = (string) subject.Value!; ··· 639 640 var eng = sctx.ParentEngine; 640 641 if (app.Functions.TryGetValue(str, out var func)) 641 642 { 642 - var fctx = func.CreateFunctionContext(sctx, args); 643 + var fctx = func.CreateFunctionContext(sctx, args.ToArray()); 643 644 result = eng.Process(fctx); 644 645 } 645 646 else if (eng.Commands.TryGetValue(str, out var cmd))
+12 -11
Prexonite/Types/StructurePType.cs
··· 91 91 { 92 92 } 93 93 94 - public PValue Invoke(StackContext sctx, PValue[] args, PCall call) 94 + public PValue Invoke(StackContext sctx, ReadOnlySpan<PValue> args, PCall call) 95 95 { 96 96 if (IsReference) 97 97 return Value.IndirectCall(sctx, args); ··· 102 102 103 103 #region IIndirectCall Members 104 104 105 - public PValue IndirectCall(StackContext sctx, PValue[] args) 105 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 106 106 { 107 107 if (IsReference) 108 108 return Value.IndirectCall(sctx, args); ··· 124 124 125 125 #region PType implementation 126 126 127 - internal static PValue[] _AddThis(PValue subject, PValue[] args) 127 + internal static PValue[] _AddThis(PValue subject, ReadOnlySpan<PValue> args) 128 128 { 129 129 var argst = new PValue[args.Length + 1]; 130 130 argst[0] = subject; 131 - Array.Copy(args, 0, argst, 1, args.Length); 131 + args.CopyTo(argst.AsSpan(1, args.Length)); 132 132 return argst; 133 133 } 134 134 ··· 144 144 public override bool TryDynamicCall( 145 145 StackContext sctx, 146 146 PValue subject, 147 - PValue[] args, 147 + ReadOnlySpan<PValue> args, 148 148 PCall call, 149 149 string id, 150 - [NotNullWhen(true)] out PValue? result 150 + [NotNullWhen(true)] 151 + out PValue? result 151 152 ) 152 153 { 153 154 result = null; ··· 204 205 } 205 206 206 207 public override bool TryStaticCall( 207 - StackContext sctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 208 + StackContext sctx, ReadOnlySpan<PValue> args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 208 209 { 209 210 result = null; 210 211 return false; ··· 361 362 /// <param name = "args">An array of arguments. Ignored in the current implementation.</param> 362 363 /// <param name = "result">The out parameter that holds the resulting PValue.</param> 363 364 /// <returns>True if the construction was successful; false otherwise.</returns> 364 - public override bool TryConstruct(StackContext sctx, PValue[] args, [NotNullWhen(true)] out PValue? result) 365 + public override bool TryConstruct(StackContext sctx, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 365 366 { 366 367 result = new(new SymbolTable<Member>(), this); 367 368 return true; ··· 412 413 } 413 414 414 415 public override bool IndirectCall( 415 - StackContext sctx, PValue subject, PValue[] args, [NotNullWhen(true)] out PValue? result) 416 + StackContext sctx, PValue subject, ReadOnlySpan<PValue> args, [NotNullWhen(true)] out PValue? result) 416 417 { 417 418 result = null; 418 419 if (subject.Value is not SymbolTable<Member> obj) ··· 461 462 return CompilationFlags.PrefersCustomImplementation; 462 463 } 463 464 464 - static readonly MethodInfo GetStructurePType = 465 + static readonly MethodInfo _getStructurePType = 465 466 typeof (PType).GetProperty(nameof(Structure))!.GetGetMethod()!; 466 467 467 468 /// <summary> ··· 471 472 /// <param name = "ins">The instruction to compile.</param> 472 473 void ICilCompilerAware.ImplementInCil(CompilerState state, Instruction ins) 473 474 { 474 - state.EmitCall(GetStructurePType); 475 + state.EmitCall(_getStructurePType); 475 476 } 476 477 477 478 #endregion
+1 -1
PrexoniteTests/PrexoniteTests.csproj
··· 3 3 <PropertyGroup> 4 4 <OutputType>Exe</OutputType> 5 5 <IsTestProject>true</IsTestProject> 6 - <TargetFramework>net8.0</TargetFramework> 6 + <TargetFramework>net9.0</TargetFramework> 7 7 <LangVersion>preview</LangVersion> 8 8 <Nullable>enable</Nullable> 9 9 </PropertyGroup>
+31
PrexoniteTests/Tests/CilCompilerTests.cs
··· 171 171 Expect(Enumerable.Range(1, 10).Select(_ => (PValue) true).ToList()); 172 172 } 173 173 174 + [Test] 175 + public void IndexAssign() 176 + { 177 + Compile( 178 + @" 179 + function main() 180 + { 181 + var results = []; 182 + results[] = true; 183 + return results; 184 + } 185 + "); 186 + _expectCil(); 187 + Expect((List<PValue>)[(PValue) true]); 188 + } 189 + 174 190 175 191 [Test] 176 192 public void JumpBreaksCilExtensions() ··· 644 660 }"); 645 661 646 662 Expect("12", true); 663 + } 664 + 665 + [Test] 666 + public void ManyParameters() 667 + { 668 + Compile( 669 + """ 670 + store_debug_implementation; 671 + function main(a, b, c, d, f) { 672 + //return a + "." + b + "." + c + "." + d + "." + f; 673 + return "a.b.c.d.f"; 674 + } 675 + """); 676 + 677 + Expect("a.b.c.d.f"); 647 678 } 648 679 }
+1 -1
PrexoniteTests/Tests/Configurations/ScriptedUnitTestContainer.cs
··· 116 116 "Test case run function (part of testing framework) not found. Was looking for {0}.", RunTestId); 117 117 if (rt == null) throw new InvalidOperationException("rt is null"); 118 118 119 - var resP = rt.Run(Engine, new[] {PType.Null, Root.CreateNativePValue(tc)}); 119 + var resP = rt.Run(Engine, [PType.Null, Root.CreateNativePValue(tc)]); 120 120 var success = (bool) resP.DynamicCall(Root, Array.Empty<PValue>(), PCall.Get, "Key").Value!; 121 121 if (success) 122 122 return;
+13 -7
PrexoniteTests/Tests/Configurations/V2UnitTestContainer.cs
··· 91 91 { 92 92 93 93 94 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, out PValue result) 94 + public bool TryDynamicCall( 95 + StackContext sctx, 96 + ReadOnlySpan<PValue> args, 97 + PCall call, 98 + string id, 99 + out PValue? result 100 + ) 95 101 { 96 102 result = PType.Null; 97 103 (string Id, Application ParentApplication) testCase; ··· 104 110 return true; 105 111 case "SUCCESS": 106 112 testCase = extract(sctx, 107 - args[0].TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, "test", out var testCaseValue) 113 + args[0].TryDynamicCall(sctx, [], PCall.Get, "test", out var testCaseValue) 108 114 ? testCaseValue 109 115 : throw new PrexoniteException("Expected test result to have a member called `test`.")); 110 116 Trace.WriteLine($"test [{sctx.ParentApplication.Module.Name}].{testCase.Id} successful"); 111 117 return true; 112 118 case "FAILURE": 113 119 testCase = extract(sctx, 114 - args[0].TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, "test", out testCaseValue) 120 + args[0].TryDynamicCall(sctx, [], PCall.Get, "test", out testCaseValue) 115 121 ? testCaseValue 116 122 : throw new PrexoniteException("Expected test result to have a member called `test`.")); 117 123 var exceptionObj = 118 - args[0].TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, "e", out var exceptionValue) 124 + args[0].TryDynamicCall(sctx, [], PCall.Get, "e", out var exceptionValue) 119 125 ? exceptionValue.Value 120 126 : throw new PrexoniteException( 121 127 "Expected failed test result to have a member called `e`"); ··· 163 169 164 170 // WHEN 165 171 // result~(Bool:Structure) 166 - var result = TestSuiteRunFunction.Run(TestSuiteEngine, new[] {ui, testCaseValue}); 172 + var result = TestSuiteRunFunction.Run(TestSuiteEngine, [ui, testCaseValue]); 167 173 168 174 // THEN 169 175 // (the UI callback should actually raise an exception in case of a test error) 170 - var ctx = new NullContext(TestSuiteEngine, TestSuiteApplication, Enumerable.Empty<string>()); 171 - Assert.IsTrue(result.TryDynamicCall(ctx, Array.Empty<PValue>(), PCall.Get, "Key", out var successfulValue), 176 + var ctx = new NullContext(TestSuiteEngine, TestSuiteApplication, []); 177 + Assert.IsTrue(result.TryDynamicCall(ctx, [], PCall.Get, "Key", out var successfulValue), 172 178 "Expected result of test run function on [{1}].{2} to have a `Key` member. Got: {0}", result, 173 179 TestSuiteApplication.Module.Name, testCaseName); 174 180 Assert.AreEqual(true, successfulValue!.Value, "Expected test [{0}].{1} to be successful.",
+8 -2
PrexoniteTests/Tests/MemberCallable.cs
··· 24 24 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 25 // IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 26 27 + using System; 27 28 using System.Diagnostics; 28 29 using NUnit.Framework; 29 30 using Prexonite; ··· 47 48 48 49 #region Implementation of IObject 49 50 50 - public bool TryDynamicCall(StackContext sctx, PValue[] args, PCall call, string id, 51 - out PValue result) 51 + public bool TryDynamicCall( 52 + StackContext sctx, 53 + ReadOnlySpan<PValue> args, 54 + PCall call, 55 + string id, 56 + out PValue? result 57 + ) 52 58 { 53 59 Assert.IsTrue(Expectations.TryGetValue(id, out var expectation), 54 60 $"A call to member {id} on object {Name} is not expected.");
+3 -3
PrexoniteTests/Tests/PartialApplication.cs
··· 87 87 public required PValue[] ClosedArguments { get; init; } 88 88 89 89 [PublicAPI] 90 - public Func<int[], PValue[], StackContext, PValue[], PValue>? IndirectCallImpl { get; set; } 90 + public Func<int[], PValue[], StackContext, ReadOnlyMemory<PValue>, PValue>? IndirectCallImpl { get; set; } 91 91 92 92 #region Implementation of IIndirectCall 93 93 94 - public PValue IndirectCall(StackContext sctx, PValue[] args) 94 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 95 95 { 96 96 var indirectCallImpl = IndirectCallImpl; 97 97 return indirectCallImpl == null 98 98 ? PType.Null 99 - : indirectCallImpl(Mappings, ClosedArguments, sctx, args); 99 + : indirectCallImpl(Mappings, ClosedArguments, sctx, args.ToImmutableArray().AsMemory()); 100 100 } 101 101 102 102 #endregion
+73 -35
PrexoniteTests/Tests/ShellExtensions.cs
··· 347 347 } 348 348 349 349 [Test] 350 - public void SpliceFunctionCall() 350 + public void SpliceFunctionCall_IndirectCall() 351 351 { 352 352 Compile(@" 353 353 function f() { ··· 357 357 function main(a, xs, b, ys, c){ 358 358 return ->f.(a, *xs, b, *ys, c); 359 359 } 360 + "); 361 + 362 + Expect(":<a><x1><x2><x3><b><y1><y2><y3><c>", 363 + "a", _list("x1", "x2", "x3"), "b", _list("y1", "y2", "y3"), "c"); 364 + Expect(":<a><x1><x2><x3><b><c>", 365 + "a", _list("x1", "x2", "x3"), "b", _list(), "c"); 366 + Expect(":<a><x1><b><c>", 367 + "a", 368 + _list("x1"), 369 + "b", 370 + _list(), 371 + "c"); 372 + } 373 + 374 + [Test] 375 + public void SpliceFunctionCall_FullSplice() 376 + { 377 + Compile(@" 378 + function f() { 379 + return call(string_concat(?), ["":""], var args >> map(x => ""<$x>"")); 380 + } 360 381 361 - function main2(xs) { 382 + function main(xs) { 362 383 return f(*xs); 363 384 } 364 385 365 - function main3(xs, ys){ 386 + "); 387 + Expect(":<x1><x2><x3>", _list("x1", "x2", "x3")); 388 + Expect(":<x1>", _list("x1")); 389 + Expect(":", _list()); 390 + Expect(":", PType.Null); 391 + } 392 + [Test] 393 + public void SpliceFunctionCall_PrefixSuffix() 394 + { 395 + Compile(@" 396 + function f() { 397 + return call(string_concat(?), ["":""], var args >> map(x => ""<$x>"")); 398 + } 399 + 400 + function main(xs, ys){ 366 401 return f(*xs, *ys); 367 402 } 403 + "); 404 + 405 + Expect(":<x1><x2><x3><y1><y2><y3>", _list("x1", "x2", "x3"), _list("y1", "y2", "y3")); 406 + Expect(":<x1><x2><x3>", _list("x1", "x2", "x3"), _list()); 407 + Expect(":<x1>", _list("x1"), _list()); 408 + Expect(":<x1>", _list("x1"), PType.Null); 409 + } 410 + [Test] 411 + public void SpliceFunctionCall_Suffix() 412 + { 413 + Compile(@" 414 + function f() { 415 + return call(string_concat(?), ["":""], var args >> map(x => ""<$x>"")); 416 + } 368 417 369 - function main4(a, b, c, xs) { 418 + function main(a, b, c, xs) { 370 419 return f(a, b, c, *xs); 371 420 } 421 + "); 422 + 423 + Expect(":<a><b><c><x1><x2><x3>", "a", "b", "c", _list("x1", "x2", "x3")); 424 + Expect(":<a><b><c><x1>", "a", "b", "c", _list("x1")); 425 + Expect(":<a><b><c>", "a", "b", "c", _list()); 426 + Expect(":<a><b><c>", "a", "b", "c", PType.Null); 427 + } 428 + [Test] 429 + public void SpliceFunctionCall_Prefix() 430 + { 431 + Compile(@" 432 + function f() { 433 + return call(string_concat(?), ["":""], var args >> map(x => ""<$x>"")); 434 + } 372 435 373 - function main5(xs, a, b, c) { 436 + function main(xs, a, b, c) { 374 437 return f(*xs, a, b, c); 375 438 } 376 439 "); 377 - 378 - Expect(":<a><x1><x2><x3><b><y1><y2><y3><c>", 379 - "a", _list("x1", "x2", "x3"), "b", _list("y1", "y2", "y3"), "c"); 380 - Expect(":<a><x1><x2><x3><b><c>", 381 - "a", _list("x1", "x2", "x3"), "b", _list(), "c"); 382 - Expect(":<a><x1><b><c>", 383 - "a", _list("x1"), "b", _list(), "c"); 384 - 385 - ExpectNamed("main2", ":<x1><x2><x3>", _list("x1", "x2", "x3")); 386 - ExpectNamed("main2", ":<x1>", _list("x1")); 387 - ExpectNamed("main2", ":", _list()); 388 - 389 - ExpectNamed("main3", ":<x1><x2><x3><y1><y2><y3>", 390 - _list("x1", "x2", "x3"), _list("y1", "y2", "y3")); 391 - ExpectNamed("main3", ":<x1><x2><x3>", 392 - _list("x1", "x2", "x3"), _list()); 393 - ExpectNamed("main3", ":<x1>", 394 - _list("x1"), _list()); 395 - 396 - ExpectNamed("main4", ":<a><b><c><x1><x2><x3>", "a", "b", "c", _list("x1", "x2", "x3")); 397 - ExpectNamed("main4", ":<a><b><c><x1>", "a", "b", "c", _list("x1")); 398 - ExpectNamed("main4", ":<a><b><c>", "a", "b", "c", _list()); 399 - ExpectNamed("main5", ":<x1><x2><x3><a><b><c>", _list("x1", "x2", "x3"), "a", "b", "c"); 400 - ExpectNamed("main5", ":<x1><a><b><c>", _list("x1"), "a", "b", "c"); 401 - ExpectNamed("main5", ":<a><b><c>", _list(), "a", "b", "c"); 402 - ExpectNamed("main4", ":<a><b><c>", "a", "b", "c", PType.Null); 403 - ExpectNamed("main5", ":<a><b><c>", PType.Null, "a", "b", "c"); 404 - ExpectNamed("main3", ":<x1>", 405 - _list("x1"), PType.Null); 406 - ExpectNamed("main2", ":", PType.Null); 440 + 441 + Expect(":<x1><x2><x3><a><b><c>", _list("x1", "x2", "x3"), "a", "b", "c"); 442 + Expect(":<x1><a><b><c>", _list("x1"), "a", "b", "c"); 443 + Expect(":<a><b><c>", _list(), "a", "b", "c"); 444 + Expect(":<a><b><c>", PType.Null, "a", "b", "c"); 407 445 } 408 446 409 447 /// <summary>
+2 -1
PrexoniteTests/Tests/Translation.cs
··· 24 24 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 25 // IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 26 27 + using System; 27 28 using System.Collections.Generic; 28 29 using System.IO; 29 30 using System.Linq; ··· 1648 1649 1649 1650 public Dictionary<string, string> VirtualFiles { get; } = new(); 1650 1651 1651 - public override PValue Run(StackContext sctx, PValue[] args) 1652 + public override PValue Run(StackContext sctx, ReadOnlySpan<PValue> args) 1652 1653 { 1653 1654 var n = args[0].CallToString(sctx); 1654 1655 var virtualFile = VirtualFiles[n];
+2 -2
PrexoniteTests/Tests/TypeSystem.cs
··· 178 178 179 179 var escaped = PType.String.CreatePValue(sEscaped); 180 180 Assert.IsTrue( 181 - escaped.TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, "unescape", out var unescaped)); 181 + escaped.TryDynamicCall(sctx, [], PCall.Get, "unescape", out var unescaped)); 182 182 Assert.AreEqual(sUnescaped, unescaped!.Value as string); 183 183 Assert.IsTrue( 184 - unescaped.TryDynamicCall(sctx, Array.Empty<PValue>(), PCall.Get, "escape", out escaped)); 184 + unescaped.TryDynamicCall(sctx, [], PCall.Get, "escape", out escaped)); 185 185 Assert.AreEqual(sEscaped, escaped!.Value as string); 186 186 } 187 187 }
+2 -2
PrexoniteTests/Tests/VMTests.Basic.cs
··· 174 174 var v0 = rnd.Next(1, 100); 175 175 var expected = 2*v0; 176 176 177 - var result = target.Functions["twice"]!.Run(engine, new PValue[] {v0}); 177 + var result = target.Functions["twice"]!.Run(engine, [v0]); 178 178 Assert.AreEqual( 179 179 PType.BuiltIn.Int, 180 180 result.Type.ToBuiltIn(), ··· 189 189 var y1 = x1 + z; 190 190 expected = y1 + x1; 191 191 192 - result = target.Functions["complicated"]!.Run(engine, new PValue[] {x0, y0}); 192 + result = target.Functions["complicated"]!.Run(engine, [x0, y0]); 193 193 Assert.AreEqual( 194 194 PType.BuiltIn.Int, 195 195 result.Type.ToBuiltIn(),
+21 -9
PrexoniteTests/Tests/VMTests.Commands.cs
··· 321 321 } 322 322 "); 323 323 324 - var check = CompilerTarget.CreateFunctionValue((s, _) => 325 - { 326 - if (s.ParentEngine.Stack.Count > 2) 324 + var check = new PValue(new ProvidedFunction((s, _) => 327 325 { 328 - foreach (var stackContext in s.ParentEngine.Stack) 329 - TestContext.WriteLine(" - " + stackContext); 326 + if (s.ParentEngine.Stack.Count > 2) 327 + { 328 + foreach (var stackContext in s.ParentEngine.Stack) 329 + TestContext.WriteLine(" - " + stackContext); 330 330 331 - throw new PrexoniteException("Stack size is not constant."); 332 - } 333 - return PType.Null; 334 - }); 331 + throw new PrexoniteException("Stack size is not constant."); 332 + } 333 + 334 + return PType.Null; 335 + }), 336 + PType.Object[typeof(IIndirectCall)]); 335 337 336 338 var fac = target.Functions["factorial"]; 337 339 Assert.IsTrue(fac!.Meta[PFunction.VolatileKey].Switch, ··· 342 344 Expect(1, check, 1); 343 345 //Expect(40320,check,8); 344 346 } 347 + 348 + class ProvidedFunction(ProvidedFunctionImpl func) : IIndirectCall 349 + { 350 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 351 + { 352 + return func(sctx, args); 353 + } 354 + } 355 + 356 + delegate PValue ProvidedFunctionImpl(StackContext sctx, ReadOnlySpan<PValue> args); 345 357 346 358 [Test] 347 359 public void CallAsyncCommandImplementation()
+2 -2
PrexoniteTests/Tests/VMTests.cs
··· 1023 1023 1024 1024 #region Implementation of IIndirectCall 1025 1025 1026 - public PValue IndirectCall(StackContext sctx, PValue[] args) 1026 + public PValue IndirectCall(StackContext sctx, params ReadOnlySpan<PValue> args) 1027 1027 { 1028 - return _impl(sctx, args); 1028 + return _impl(sctx, args.ToArray()); 1029 1029 } 1030 1030 1031 1031 #endregion
+10 -9
PrexoniteTests/Tests/VMTestsBase.cs
··· 190 190 return Store(Compile(input)); 191 191 } 192 192 193 - protected void Expect<T>(T expectedReturnValue, params PValue[] args) 193 + protected void Expect<T>(T expectedReturnValue, params ReadOnlySpan<PValue> args) 194 194 { 195 195 ExpectReturnValue(target.Meta[Application.EntryKey], expectedReturnValue, args); 196 196 } 197 197 198 - protected void Expect(Action<PValue> assertion, params PValue[] args) 198 + protected void Expect(Action<PValue> assertion, params ReadOnlySpan<PValue> args) 199 199 { 200 200 ExpectReturnValue(target.Meta[Application.EntryKey], assertion, args); 201 201 } 202 202 203 - protected void ExpectNamed<T>(string functionId, T expectedReturnValue, params PValue[] args) 203 + protected void ExpectNamed<T>(string functionId, T expectedReturnValue, params ReadOnlySpan<PValue> args) 204 204 { 205 205 ExpectReturnValue(functionId, expectedReturnValue, args); 206 206 } 207 207 208 - protected void ExpectReturnValue<T>(string functionId, T expectedReturnValue, PValue[] args) 208 + protected void ExpectReturnValue<T>(string functionId, T expectedReturnValue, ReadOnlySpan<PValue> args) 209 209 { 210 210 ExpectReturnValue(functionId, rv => 211 211 { ··· 214 214 }, args); 215 215 } 216 216 217 - protected void ExpectReturnValue(string functionId, Action<PValue> assertion, PValue[] args) 217 + protected void ExpectReturnValue(string functionId, Action<PValue> assertion, ReadOnlySpan<PValue> args) 218 218 { 219 219 if (assertion == null) 220 220 throw new ArgumentNullException(nameof(assertion)); 221 - 222 - if (args.Any(value => (PValue?)value == null)) 223 - throw new ArgumentException( 224 - "Arguments must not contain naked CLR null references. Use `PType.Null`."); 221 + 222 + foreach (var value in args) 223 + { 224 + if ((PValue?)value == null) throw new ArgumentException("Arguments must not contain naked CLR null references. Use `PType.Null`."); 225 + } 225 226 226 227 if (!target.Functions.Contains(functionId)) 227 228 throw new PrexoniteException("Function " + functionId + " cannot be found.");
+7 -2
Prx/Benchmarking/Benchmark.cs
··· 128 128 #region IObject Members 129 129 130 130 public bool TryDynamicCall( 131 - StackContext sctx, PValue[]? args, PCall call, string? id, [NotNullWhen(true)] out PValue? result) 131 + StackContext sctx, 132 + ReadOnlySpan<PValue> args, 133 + PCall call, 134 + string id, 135 + [NotNullWhen(true)] 136 + out PValue? result 137 + ) 132 138 { 133 139 if (sctx == null) 134 140 throw new ArgumentNullException(nameof(sctx)); 135 - args ??= Array.Empty<PValue>(); 136 141 id ??= ""; 137 142 138 143 result = null;
+1 -2
Prx/Benchmarking/BenchmarkEntry.cs
··· 126 126 Console.WriteLine("\tIterations:\t{0}", iterations); 127 127 } 128 128 129 - var argv = new PValue[] {iterations}; 130 129 sw.Reset(); 131 130 sw.Start(); 132 - Function.Run(Parent.Machine, argv); 131 + Function.Run(Parent.Machine, [iterations]); 133 132 sw.Stop(); 134 133 135 134 var raw = sw.ElapsedMilliseconds;
+9 -3
Prx/PrexoniteConsole.cs
··· 64 64 Resources.PrexoniteConsole_OnTab_RequiresSctx); 65 65 if (Tab is { IsNull: false }) 66 66 { 67 - var plst = Tab.IndirectCall(callingSctx, new PValue[] {pref, root}); 67 + var plst = Tab.IndirectCall(callingSctx, pref, root); 68 68 plst.ConvertTo(callingSctx, PType.Object[typeof (IEnumerable)], true); 69 69 foreach (var o in (IEnumerable) plst.Value!) 70 70 { ··· 81 81 /// <param name = "callingSctx">The stack context in which the command is executed.</param> 82 82 /// <param name = "args">The array of arguments supplied to the command.</param> 83 83 /// <returns>A reference to the prexonite console.</returns> 84 - public PValue Run(StackContext callingSctx, PValue[] args) 84 + public PValue Run(StackContext callingSctx, ReadOnlySpan<PValue> args) 85 85 { 86 86 return callingSctx.CreateNativePValue(this); 87 87 } ··· 98 98 StackContext? sctx; 99 99 100 100 public bool TryDynamicCall( 101 - StackContext callingSctx, PValue[] args, PCall call, string id, [NotNullWhen(true)] out PValue? result) 101 + StackContext callingSctx, 102 + ReadOnlySpan<PValue> args, 103 + PCall call, 104 + string id, 105 + [NotNullWhen(true)] 106 + out PValue? result 107 + ) 102 108 { 103 109 result = null; 104 110
+69 -69
Prx/Properties/Resources.Designer.cs
··· 1 - //------------------------------------------------------------------------------ 2 - // <auto-generated> 3 - // This code was generated by a tool. 4 - // 5 - // Changes to this file may cause incorrect behavior and will be lost if 6 - // the code is regenerated. 7 - // </auto-generated> 8 - //------------------------------------------------------------------------------ 9 - 10 - namespace Prx.Properties { 11 - using System; 12 - 13 - 14 - /// <summary> 15 - /// A strongly-typed resource class, for looking up localized strings, etc. 16 - /// This class was generated by MSBuild using the GenerateResource task. 17 - /// To add or remove a member, edit your .resx file then rerun MSBuild. 18 - /// </summary> 19 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] 20 - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 21 - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 22 - internal class Resources { 23 - 24 - private static global::System.Resources.ResourceManager resourceMan; 25 - 26 - private static global::System.Globalization.CultureInfo resourceCulture; 27 - 28 - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 29 - internal Resources() { 30 - } 31 - 32 - /// <summary> 33 - /// Returns the cached ResourceManager instance used by this class. 34 - /// </summary> 35 - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 36 - internal static global::System.Resources.ResourceManager ResourceManager { 37 - get { 38 - if (object.ReferenceEquals(resourceMan, null)) { 39 - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Prx.Properties.Resources", typeof(Resources).Assembly); 40 - resourceMan = temp; 41 - } 42 - return resourceMan; 43 - } 44 - } 45 - 46 - /// <summary> 47 - /// Overrides the current thread's CurrentUICulture property for all 48 - /// resource lookups using this strongly typed resource class. 49 - /// </summary> 50 - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 51 - internal static global::System.Globalization.CultureInfo Culture { 52 - get { 53 - return resourceCulture; 54 - } 55 - set { 56 - resourceCulture = value; 57 - } 58 - } 59 - 60 - /// <summary> 61 - /// Looks up a localized string similar to OnTab must either be called from via the ReadLine method or with a valid stack context.. 62 - /// </summary> 63 - internal static string PrexoniteConsole_OnTab_RequiresSctx { 64 - get { 65 - return ResourceManager.GetString("PrexoniteConsole_OnTab_RequiresSctx", resourceCulture); 66 - } 67 - } 68 - } 69 - } 1 + //------------------------------------------------------------------------------ 2 + // <auto-generated> 3 + // This code was generated by a tool. 4 + // 5 + // Changes to this file may cause incorrect behavior and will be lost if 6 + // the code is regenerated. 7 + // </auto-generated> 8 + //------------------------------------------------------------------------------ 9 + 10 + namespace Prx.Properties { 11 + using System; 12 + 13 + 14 + /// <summary> 15 + /// A strongly-typed resource class, for looking up localized strings, etc. 16 + /// This class was generated by MSBuild using the GenerateResource task. 17 + /// To add or remove a member, edit your .resx file then rerun MSBuild. 18 + /// </summary> 19 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] 20 + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 21 + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 22 + internal class Resources { 23 + 24 + private static global::System.Resources.ResourceManager resourceMan; 25 + 26 + private static global::System.Globalization.CultureInfo resourceCulture; 27 + 28 + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 29 + internal Resources() { 30 + } 31 + 32 + /// <summary> 33 + /// Returns the cached ResourceManager instance used by this class. 34 + /// </summary> 35 + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 36 + internal static global::System.Resources.ResourceManager ResourceManager { 37 + get { 38 + if (object.ReferenceEquals(resourceMan, null)) { 39 + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Prx.Properties.Resources", typeof(Resources).Assembly); 40 + resourceMan = temp; 41 + } 42 + return resourceMan; 43 + } 44 + } 45 + 46 + /// <summary> 47 + /// Overrides the current thread's CurrentUICulture property for all 48 + /// resource lookups using this strongly typed resource class. 49 + /// </summary> 50 + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 51 + internal static global::System.Globalization.CultureInfo Culture { 52 + get { 53 + return resourceCulture; 54 + } 55 + set { 56 + resourceCulture = value; 57 + } 58 + } 59 + 60 + /// <summary> 61 + /// Looks up a localized string similar to OnTab must either be called from via the ReadLine method or with a valid stack context.. 62 + /// </summary> 63 + internal static string PrexoniteConsole_OnTab_RequiresSctx { 64 + get { 65 + return ResourceManager.GetString("PrexoniteConsole_OnTab_RequiresSctx", resourceCulture); 66 + } 67 + } 68 + } 69 + }
+1 -1
Prx/Prx.csproj
··· 6 6 7 7 <PropertyGroup> 8 8 <OutputType>exe</OutputType> 9 - <TargetFramework>net8.0</TargetFramework> 9 + <TargetFramework>net9.0</TargetFramework> 10 10 <AppConfig>config/app.$(Configuration).config</AppConfig> 11 11 <LangVersion>preview</LangVersion> 12 12 <Version>1.99</Version>