diff --git a/src/Peachpie.CodeAnalysis/CodeGen/CodeGenerator.Emit.cs b/src/Peachpie.CodeAnalysis/CodeGen/CodeGenerator.Emit.cs index b9ffac2877..8e6f2f8a9e 100644 --- a/src/Peachpie.CodeAnalysis/CodeGen/CodeGenerator.Emit.cs +++ b/src/Peachpie.CodeAnalysis/CodeGen/CodeGenerator.Emit.cs @@ -2583,11 +2583,11 @@ protected virtual void WriteBackAndFree(CodeGenerator cg) public static void WriteBackAndFree(CodeGenerator cg, IList writebacks) { - if (writebacks != null && writebacks.Count != 0) + if (writebacks != null) { - foreach (var w in writebacks) + for (int i = 0; i < writebacks.Count; i++) { - w.WriteBackAndFree(cg); + writebacks[i].WriteBackAndFree(cg); } } } diff --git a/src/Peachpie.Library/Arrays.cs b/src/Peachpie.Library/Arrays.cs index ecc95f5701..06118973d3 100644 --- a/src/Peachpie.Library/Arrays.cs +++ b/src/Peachpie.Library/Arrays.cs @@ -1,5 +1,6 @@ using Pchp.Core; using Pchp.Core.Resources; +using Pchp.Core.Utilities; using Pchp.Library.Resources; using System; using System.Collections; @@ -533,8 +534,15 @@ public static PhpValue array_rand(PhpArray array, int count = 1) { if (count == 1) { - var result = new List(1); - return RandomSubset(array.Keys, result, count, PhpMath.Generator) ? result[0] : PhpValue.Null; + var result = ListPool.Pool.Get(); + try + { + return RandomSubset(array.Keys, result, count, PhpMath.Generator) ? result[0] : PhpValue.Null; + } + finally + { + ListPool.Pool.Return(result); + } } else { diff --git a/src/Peachpie.Library/FileSystem.Glob.cs b/src/Peachpie.Library/FileSystem.Glob.cs index da34327102..e7b85c03e3 100644 --- a/src/Peachpie.Library/FileSystem.Glob.cs +++ b/src/Peachpie.Library/FileSystem.Glob.cs @@ -148,13 +148,13 @@ public string MakeString() } } - sealed class GlobMatcher + sealed class GlobMatcher : IDisposable { readonly Context/*!*/_ctx; readonly string/*!*/ _pattern; readonly GlobOptions _flags; - readonly List/*!*/ _result; readonly bool _dirOnly; + List/*!*/ _result; bool _stripTwo; bool _relative; FnMatchOptions _fnMatchFlags; @@ -172,12 +172,19 @@ public GlobMatcher(Context ctx, string/*!*/pattern, GlobOptions flags) _ctx = ctx; _pattern = pattern; _flags = flags; - _result = new List(); + _result = ListPool.Pool.Get(); _dirOnly = PathUtils.IsDirectorySeparator((char)_pattern.LastCharacter()) || (flags & GlobOptions.OnlyDir) != 0; _fnMatchFlags = NoEscapes ? FnMatchOptions.NoEscape : FnMatchOptions.None; } + public void Dispose() + { + ListPool.Pool.Return(_result); + _result = null; + } + + bool IsDisposed => _result == null; private static string/*!*/ Unescape(string/*!*/ path, int start) { @@ -243,6 +250,11 @@ private void TestPath(string path, int patternEnd, bool isLastPathSegment) internal List/*!*/ DoGlob() { + if (IsDisposed) + { + throw new ObjectDisposedException(nameof(GlobMatcher)); + } + if (_pattern.Length == 0) { return _result; @@ -790,7 +802,7 @@ static ValueList UngroupGlobs(string/*!*/ pattern, bool noEscape, bool b foreach (string group in groups) { - var matcher = new GlobMatcher(ctx, group, flags); + using var matcher = new GlobMatcher(ctx, group, flags); foreach (string filename in matcher.DoGlob()) {