Created
December 20, 2021 09:18
-
-
Save olivier-spinelli/2697fbbe124f377056786e9284882a38 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
public ref struct ROSpanMatcher | |
{ | |
public ReadOnlySpan<char> Head; | |
public int _le; | |
public ROSpanMatcher( ReadOnlySpan<char> text ) | |
{ | |
Head = text; | |
_le = 7; | |
} | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public int UncheckedForward( int length ) | |
{ | |
// Slice throws ArgumentOutOfRangeException if length is negative. | |
Head = Head[length..]; | |
return Head.Length; | |
} | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public int Forward( int length ) | |
{ | |
// Slice throws ArgumentOutOfRangeException if length is negative. | |
Head = Head.Slice( Math.Min( length, Head.Length ) ); | |
return Head.Length; | |
} | |
} | |
public class C { | |
public static bool TryMatch( ref ReadOnlySpan<char> h, out char color ) | |
{ | |
color = default; | |
if( h.Length == 0 ) return false; | |
switch( h[0] ) | |
{ | |
case 'W': color = 'w'; break; | |
case 'R': color = 'r'; break; | |
case 'G': color = 'g'; break; | |
default: return false; | |
}; | |
h = h.Slice( 1 ); | |
return true; | |
} | |
// 3 more bytes. | |
public static bool TryMatch( ref ROSpanMatcher h, out char color ) | |
{ | |
color = default; | |
if( h.Head.Length == 0 ) return false; | |
switch( h.Head[0] ) | |
{ | |
case 'W': color = 'w'; break; | |
case 'R': color = 'r'; break; | |
case 'G': color = 'g'; break; | |
default: return false; | |
}; | |
h.Head = h.Head.Slice( 1 ); | |
return true; | |
} | |
// Using the range operator costs 9 bytes... | |
public static bool TryMatchBad( ref ROSpanMatcher h, out char color ) | |
{ | |
color = default; | |
if( h.Head.Length == 0 ) return false; | |
switch( h.Head[0] ) | |
{ | |
case 'W': color = 'w'; break; | |
case 'R': color = 'r'; break; | |
case 'G': color = 'g'; break; | |
default: return false; | |
}; | |
h.Head = h.Head[1..]; | |
return true; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Core CLR 6.0.21.52210 on amd64 | |
ROSpanMatcher..ctor(System.ReadOnlySpan`1<Char>) | |
L0000: push rdi | |
L0001: push rsi | |
L0002: push rbx | |
L0003: mov rbx, rcx | |
L0006: mov rdi, rbx | |
L0009: mov rsi, rdx | |
L000c: call 0x00007ffd108ca640 | |
L0011: movsq [rdi], [rsi] | |
L0013: mov dword ptr [rbx+0x10], 7 | |
L001a: pop rbx | |
L001b: pop rsi | |
L001c: pop rdi | |
L001d: ret | |
ROSpanMatcher.UncheckedForward(Int32) | |
L0000: sub rsp, 0x28 | |
L0004: mov rax, [rcx] | |
L0007: mov r8d, [rcx+8] | |
L000b: mov r9d, r8d | |
L000e: sub r9d, edx | |
L0011: mov edx, edx | |
L0013: mov r10d, r9d | |
L0016: add r10, rdx | |
L0019: mov r8d, r8d | |
L001c: cmp r10, r8 | |
L001f: ja short L0034 | |
L0021: lea rax, [rax+rdx*2] | |
L0025: mov [rcx], rax | |
L0028: mov [rcx+8], r9d | |
L002c: mov eax, [rcx+8] | |
L002f: add rsp, 0x28 | |
L0033: ret | |
L0034: call 0x00007ffcb0fa5680 | |
L0039: int3 | |
ROSpanMatcher.Forward(Int32) | |
L0000: sub rsp, 0x28 | |
L0004: mov rax, rcx | |
L0007: mov eax, [rax+8] | |
L000a: mov r8d, eax | |
L000d: cmp edx, r8d | |
L0010: jg short L002f | |
L0012: cmp edx, eax | |
L0014: ja short L0036 | |
L0016: mov r8, [rcx] | |
L0019: sub eax, edx | |
L001b: mov edx, edx | |
L001d: lea rdx, [r8+rdx*2] | |
L0021: mov [rcx], rdx | |
L0024: mov [rcx+8], eax | |
L0027: mov eax, [rcx+8] | |
L002a: add rsp, 0x28 | |
L002e: ret | |
L002f: mov edx, r8d | |
L0032: cmp edx, eax | |
L0034: jbe short L0016 | |
L0036: call 0x00007ffcb0fa5680 | |
L003b: int3 | |
C..ctor() | |
L0000: ret | |
C.TryMatch(System.ReadOnlySpan`1<Char> ByRef, Char ByRef) | |
L0000: sub rsp, 0x28 | |
L0004: mov word ptr [rdx], 0 | |
L0009: mov eax, [rcx+8] | |
L000c: test eax, eax | |
L000e: jne short L0017 | |
L0010: xor eax, eax | |
L0012: add rsp, 0x28 | |
L0016: ret | |
L0017: mov rax, [rcx] | |
L001a: movzx eax, word ptr [rax] | |
L001d: cmp eax, 0x47 | |
L0020: je short L003a | |
L0022: cmp eax, 0x52 | |
L0025: je short L0033 | |
L0027: cmp eax, 0x57 | |
L002a: jne short L005f | |
L002c: mov word ptr [rdx], 0x77 | |
L0031: jmp short L003f | |
L0033: mov word ptr [rdx], 0x72 | |
L0038: jmp short L003f | |
L003a: mov word ptr [rdx], 0x67 | |
L003f: mov eax, [rcx+8] | |
L0042: test eax, eax | |
L0044: je short L0066 | |
L0046: mov rdx, [rcx] | |
L0049: dec eax | |
L004b: add rdx, 2 | |
L004f: mov [rcx], rdx | |
L0052: mov [rcx+8], eax | |
L0055: mov eax, 1 | |
L005a: add rsp, 0x28 | |
L005e: ret | |
L005f: xor eax, eax | |
L0061: add rsp, 0x28 | |
L0065: ret | |
L0066: call 0x00007ffcb0fa5680 | |
L006b: int3 | |
C.TryMatch(ROSpanMatcher ByRef, Char ByRef) | |
L0000: sub rsp, 0x28 | |
L0004: mov word ptr [rdx], 0 | |
L0009: mov eax, [rcx+8] | |
L000c: test eax, eax | |
L000e: jne short L0017 | |
L0010: xor eax, eax | |
L0012: add rsp, 0x28 | |
L0016: ret | |
L0017: mov rax, [rcx] | |
L001a: movzx eax, word ptr [rax] | |
L001d: cmp eax, 0x47 | |
L0020: je short L003a | |
L0022: cmp eax, 0x52 | |
L0025: je short L0033 | |
L0027: cmp eax, 0x57 | |
L002a: jne short L0062 | |
L002c: mov word ptr [rdx], 0x77 | |
L0031: jmp short L003f | |
L0033: mov word ptr [rdx], 0x72 | |
L0038: jmp short L003f | |
L003a: mov word ptr [rdx], 0x67 | |
L003f: mov rax, rcx | |
L0042: mov eax, [rax+8] | |
L0045: test eax, eax | |
L0047: je short L0069 | |
L0049: mov rdx, [rcx] | |
L004c: dec eax | |
L004e: add rdx, 2 | |
L0052: mov [rcx], rdx | |
L0055: mov [rcx+8], eax | |
L0058: mov eax, 1 | |
L005d: add rsp, 0x28 | |
L0061: ret | |
L0062: xor eax, eax | |
L0064: add rsp, 0x28 | |
L0068: ret | |
L0069: call 0x00007ffcb0fa5680 | |
L006e: int3 | |
C.TryMatchBad(ROSpanMatcher ByRef, Char ByRef) | |
L0000: sub rsp, 0x28 | |
L0004: mov word ptr [rdx], 0 | |
L0009: mov eax, [rcx+8] | |
L000c: test eax, eax | |
L000e: jne short L0017 | |
L0010: xor eax, eax | |
L0012: add rsp, 0x28 | |
L0016: ret | |
L0017: mov rax, [rcx] | |
L001a: movzx eax, word ptr [rax] | |
L001d: cmp eax, 0x47 | |
L0020: je short L003a | |
L0022: cmp eax, 0x52 | |
L0025: je short L0033 | |
L0027: cmp eax, 0x57 | |
L002a: jne short L006b | |
L002c: mov word ptr [rdx], 0x77 | |
L0031: jmp short L003f | |
L0033: mov word ptr [rdx], 0x72 | |
L0038: jmp short L003f | |
L003a: mov word ptr [rdx], 0x67 | |
L003f: mov rax, [rcx] | |
L0042: mov edx, [rcx+8] | |
L0045: lea r8d, [rdx-1] | |
L0049: mov r9d, r8d | |
L004c: inc r9 | |
L004f: mov edx, edx | |
L0051: cmp r9, rdx | |
L0054: ja short L0072 | |
L0056: add rax, 2 | |
L005a: mov [rcx], rax | |
L005d: mov [rcx+8], r8d | |
L0061: mov eax, 1 | |
L0066: add rsp, 0x28 | |
L006a: ret | |
L006b: xor eax, eax | |
L006d: add rsp, 0x28 | |
L0071: ret | |
L0072: call 0x00007ffcb0fa5680 | |
L0077: int3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": 1, | |
"target": "JIT ASM", | |
"mode": "Release", | |
"branch": "core-x64" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment