diff --git a/ExternalProjects/NLua/NLua.csproj b/ExternalProjects/NLua/NLua.csproj
index be621ecfa8..a01032d2ef 100644
--- a/ExternalProjects/NLua/NLua.csproj
+++ b/ExternalProjects/NLua/NLua.csproj
@@ -26,4 +26,8 @@
disable
true
+
+
+
+
diff --git a/ExternalProjects/NLua/src/Native/LuaNativeMethods.cs b/ExternalProjects/NLua/src/Native/LuaNativeMethods.cs
index e44ab6142a..7688b487f0 100644
--- a/ExternalProjects/NLua/src/Native/LuaNativeMethods.cs
+++ b/ExternalProjects/NLua/src/Native/LuaNativeMethods.cs
@@ -1,4 +1,5 @@
-using System.Runtime.CompilerServices;
+using System;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
@@ -184,7 +185,7 @@ namespace NLua.Native
internal delegate* unmanaged[Cdecl] lua_pushlstring;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public charptr_t PushLString(lua_State luaState, byte[] s, size_t len)
+ public charptr_t PushLString(lua_State luaState, ReadOnlySpan s, size_t len)
{
fixed (byte* _s = s)
{
diff --git a/ExternalProjects/NLua/src/Native/LuaState.cs b/ExternalProjects/NLua/src/Native/LuaState.cs
index 71b93be434..fcf6815e7c 100644
--- a/ExternalProjects/NLua/src/Native/LuaState.cs
+++ b/ExternalProjects/NLua/src/Native/LuaState.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -355,7 +356,7 @@ namespace NLua.Native
/// Pushes binary buffer onto the stack (usually UTF encoded string) or any arbitraty binary data
///
///
- public void PushBuffer(byte[] buffer)
+ public void PushBuffer(ReadOnlySpan buffer)
{
if (buffer == null)
{
@@ -378,8 +379,11 @@ namespace NLua.Native
return;
}
- var buffer = Encoding.UTF8.GetBytes(value);
- PushBuffer(buffer);
+ // could also use GetByteCount here, but why iterate twice when we're renting the memory anyway?
+ byte[] buffer = ArrayPool.Shared.Rent(Encoding.UTF8.GetMaxByteCount(value.Length));
+ int actualLength = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, 0);
+ PushBuffer(buffer.AsSpan(0, actualLength));
+ ArrayPool.Shared.Return(buffer);
}
///
@@ -556,13 +560,7 @@ namespace NLua.Native
public long ToInteger(int index)
=> NativeMethods.ToIntegerX(Handle, index, out _);
- ///
- /// Converts the Lua value at the given index to a byte array.
- ///
- ///
- /// Calls __tostring field if present
- ///
- public byte[] ToBuffer(int index, bool callMetamethod = true)
+ private IntPtr ToLString(int index, bool callMetamethod, out int stringLength)
{
UIntPtr len;
IntPtr buff;
@@ -577,19 +575,26 @@ namespace NLua.Native
buff = NativeMethods.ToLString(Handle, index, out len);
}
- if (buff == IntPtr.Zero)
- {
- return null;
- }
+ stringLength = (int)len;
- var length = (int)len;
- if (length == 0)
- {
- return Array.Empty();
- }
+ return buff;
+ }
+
+ ///
+ /// Converts the Lua value at the given index to a byte array.
+ ///
+ ///
+ /// Calls __tostring field if present
+ ///
+ public byte[] ToBuffer(int index, bool callMetamethod = true)
+ {
+ IntPtr buffer = ToLString(index, callMetamethod, out int length);
+
+ if (buffer == IntPtr.Zero) return null;
+ if (length == 0) return Array.Empty();
var output = new byte[length];
- Marshal.Copy(buff, output, 0, length);
+ Marshal.Copy(buffer, output, 0, length);
return output;
}
@@ -601,8 +606,15 @@ namespace NLua.Native
///
public string ToString(int index, bool callMetamethod = true)
{
- var buffer = ToBuffer(index, callMetamethod);
- return buffer == null ? null : Encoding.UTF8.GetString(buffer);
+ var buffer = ToLString(index, callMetamethod, out int length);
+
+ if (buffer == IntPtr.Zero) return null;
+ if (length == 0) return "";
+
+ unsafe
+ {
+ return Encoding.UTF8.GetString((byte*)buffer.ToPointer(), length);
+ }
}
///
diff --git a/References/NLua.dll b/References/NLua.dll
index 07a5627d2a..281a5f76b0 100644
Binary files a/References/NLua.dll and b/References/NLua.dll differ