Skip to content

Instantly share code, notes, and snippets.

@ogxd
Created September 24, 2024 13:17
Show Gist options
  • Save ogxd/428f61c441c7eb7857f579a0714afbeb to your computer and use it in GitHub Desktop.
Save ogxd/428f61c441c7eb7857f579a0714afbeb to your computer and use it in GitHub Desktop.
using System;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
public class C {
public void M() {
lamba = (x) => A(x) && B(x);
var parameter = Expression.Parameter(typeof(int), "x");
var aMethod = typeof(C).GetMethod("A", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var bMethod = typeof(C).GetMethod("B", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var aCall = Expression.Call(Expression.Constant(this), aMethod, parameter);
var bCall = Expression.Call(Expression.Constant(this), bMethod, parameter);
var andExpression = Expression.AndAlso(aCall, bCall);
dynamicLambda = Expression.Lambda<Func<int, bool>>(andExpression, parameter).Compile();
Classic(42);
Lambda(42);
RuntimeLambda(42);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private bool Classic(int x) {
return A(x) && B(x);
}
private Func<int, bool> lamba;
private Func<int, bool> dynamicLambda;
[MethodImpl(MethodImplOptions.NoInlining)]
private bool Lambda(int x) {
return lamba(x);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private bool RuntimeLambda(int x) {
return dynamicLambda(x);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool A(int x) {
return x % 2 == 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool B(int x) {
return x / 2 == 0;
}
}
; Core CLR 8.0.724.31311 on x64
C..ctor()
L0000: ret
C.M()
L0000: push rbp
L0001: push r15
L0003: push r14
L0005: push r13
L0007: push rdi
L0008: push rsi
L0009: push rbx
L000a: sub rsp, 0x50
L000e: lea rbp, [rsp+0x80]
L0016: xor eax, eax
L0018: mov [rbp-0x38], rax
L001c: mov rbx, rcx
L001f: mov rcx, 0x7ffbe2506820
L0029: call 0x00007ffbd7c4ca50
L002e: mov rsi, rax
L0031: test rbx, rbx
L0034: je L02f3
L003a: lea rcx, [rsi+8]
L003e: mov rdx, rbx
L0041: call 0x00007ffb77f80010
L0046: mov rcx, 0x7ffbf2ce00a8
L0050: mov [rsi+0x18], rcx
L0054: lea rcx, [rbx+8]
L0058: mov rdx, rsi
L005b: call 0x00007ffb77f80010
L0060: mov rsi, 0x28aef223640
L006a: mov rcx, 0x28aef223640
L0074: mov rdx, 0x28aef220370
L007e: mov r8d, 0xffffffff
L0084: call qword ptr [0x7ffb786252f0]
L008a: test eax, eax
L008c: je short L00a6
L008e: mov rcx, 0x28aef223640
L0098: call 0x00007ffbd7bfb7a0
L009d: cmp eax, 0xf
L00a0: je L02fa
L00a6: mov rcx, 0x28aef223640
L00b0: call 0x00007ffbd7bfb7a0
L00b5: xor edx, edx
L00b7: cmp eax, 0x10
L00ba: sete dl
L00bd: movzx edi, dl
L00c1: test edi, edi
L00c3: jne L031f
L00c9: mov rdx, 0x287ab221828
L00d3: mov rdx, [rdx]
L00d6: mov rcx, rsi
L00d9: mov r8d, edi
L00dc: call qword ptr [0x7ffb78625410]
L00e2: mov rdi, rax
L00e5: mov rcx, 0x7ffbf2cdce60
L00ef: call 0x00007ffbd7bedfd0
L00f4: mov rsi, rax
L00f7: mov rcx, rsi
L00fa: xor edx, edx
L00fc: mov [rsp+0x20], rdx
L0101: mov dword ptr [rsp+0x28], 3
L0109: mov [rsp+0x30], rdx
L010e: mov [rsp+0x38], rdx
L0113: mov rdx, 0x28af668d8d8
L011d: mov rdx, [rdx]
L0120: mov r8d, 0xffffffff
L0126: mov r9d, 0x24
L012c: call qword ptr [0x7ffb78036838]
L0132: mov r14, rax
L0135: mov rcx, rsi
L0138: xor edx, edx
L013a: mov [rsp+0x20], rdx
L013f: mov dword ptr [rsp+0x28], 3
L0147: mov [rsp+0x30], rdx
L014c: mov [rsp+0x38], rdx
L0151: mov rdx, 0x287abc675e0
L015b: mov rdx, [rdx]
L015e: mov r8d, 0xffffffff
L0164: mov r9d, 0x24
L016a: call qword ptr [0x7ffb78036838]
L0170: mov rsi, rax
L0173: mov rcx, 0x7ffb78e9c190
L017d: call 0x00007ffbd7c4ca50
L0182: mov r15, rax
L0185: lea rcx, [r15+8]
L0189: mov rdx, rbx
L018c: call 0x00007ffb77f80010
L0191: mov rcx, 0x7ffb785fe640
L019b: mov edx, 1
L01a0: call 0x00007ffbd7c4cc10
L01a5: mov r13, rax
L01a8: lea rcx, [r13+0x10]
L01ac: mov rdx, rdi
L01af: call 0x00007ffb77f80010
L01b4: mov rcx, r15
L01b7: mov rdx, r14
L01ba: mov r8, r13
L01bd: call qword ptr [0x7ffb78624450]
L01c3: mov r14, rax
L01c6: mov rcx, 0x7ffb78e9c190
L01d0: call 0x00007ffbd7c4ca50
L01d5: mov r15, rax
L01d8: lea rcx, [r15+8]
L01dc: mov rdx, rbx
L01df: call 0x00007ffb77f80010
L01e4: mov rcx, 0x7ffb785fe640
L01ee: mov edx, 1
L01f3: call 0x00007ffbd7c4cc10
L01f8: mov r13, rax
L01fb: lea rcx, [r13+0x10]
L01ff: mov rdx, rdi
L0202: call 0x00007ffb77f80010
L0207: mov rcx, r15
L020a: mov rdx, rsi
L020d: mov r8, r13
L0210: call qword ptr [0x7ffb78624450]
L0216: mov rdx, rax
L0219: mov rcx, r14
L021c: xor r8d, r8d
L021f: call qword ptr [0x7ffb785ae418]
L0225: mov rsi, rax
L0228: mov rcx, 0x7ffb78630c90
L0232: mov edx, 1
L0237: call 0x00007ffbd7c4cc10
L023c: mov r14, rax
L023f: lea rcx, [r14+0x10]
L0243: mov rdx, rdi
L0246: call 0x00007ffb77f80010
L024b: mov [rbp-0x38], rsi
L024f: mov rdx, r14
L0252: mov rcx, 0x7ffb78630f70
L025c: call qword ptr [0x7ffb786258d8]
L0262: mov rsi, rax
L0265: lea rdx, [rbp-0x38]
L0269: mov r8, rsi
L026c: mov rcx, 0x28aef3215d0
L0276: mov r9, 0x28aef22d398
L0280: call qword ptr [0x7ffb785af750]
L0286: mov [rsp+0x20], rsi
L028b: mov rdx, [rbp-0x38]
L028f: mov rcx, 0x7ffbe2506988
L0299: xor r8d, r8d
L029c: xor r9d, r9d
L029f: call qword ptr [0x7ffb78627648]
L02a5: mov rcx, rax
L02a8: cmp [rcx], ecx
L02aa: call qword ptr [0x7ffb786275a0]
L02b0: lea rcx, [rbx+0x10]
L02b4: mov rdx, rax
L02b7: call 0x00007ffb77f80010
L02bc: mov rcx, rbx
L02bf: mov edx, 0x2a
L02c4: call 0x00007ffbf2ce0018
L02c9: mov rcx, rbx
L02cc: mov edx, 0x2a
L02d1: call 0x00007ffbf2ce0030
L02d6: mov rcx, rbx
L02d9: mov edx, 0x2a
L02de: call 0x00007ffbf2ce0048
L02e3: nop
L02e4: add rsp, 0x50
L02e8: pop rbx
L02e9: pop rsi
L02ea: pop rdi
L02eb: pop r13
L02ed: pop r14
L02ef: pop r15
L02f1: pop rbp
L02f2: ret
L02f3: call qword ptr [0x7ffb780e41f8]
L02f9: int3
L02fa: mov ecx, 0x2ecb
L02ff: mov rdx, 0x7ffb785f5b40
L0309: call 0x00007ffbd7b79620
L030e: mov rcx, rax
L0311: call qword ptr [0x7ffb78776c10]
L0317: mov rcx, rax
L031a: call 0x00007ffbd7baad10
L031f: mov rcx, 0x28aef223640
L0329: mov rax, [0x7ffb7802a380]
L0330: call qword ptr [rax+8]
L0333: mov rsi, rax
L0336: jmp L00c9
C.Classic(Int32)
L0000: test dl, 1
L0003: jne short L0015
L0005: mov eax, edx
L0007: shr eax, 0x1f
L000a: add eax, edx
L000c: sar eax, 1
L000e: sete al
L0011: movzx eax, al
L0014: ret
L0015: xor eax, eax
L0017: ret
C.Lambda(Int32)
L0000: sub rsp, 0x28
L0004: mov rax, [rcx+8]
L0008: mov rcx, [rax+8]
L000c: call qword ptr [rax+0x18]
L000f: nop
L0010: add rsp, 0x28
L0014: ret
C.RuntimeLambda(Int32)
L0000: sub rsp, 0x28
L0004: mov rax, [rcx+0x10]
L0008: mov rcx, [rax+8]
L000c: call qword ptr [rax+0x18]
L000f: nop
L0010: add rsp, 0x28
L0014: ret
C.A(Int32)
L0000: mov eax, edx
L0002: not eax
L0004: and eax, 1
L0007: ret
C.B(Int32)
L0000: mov eax, edx
L0002: shr eax, 0x1f
L0005: add eax, edx
L0007: sar eax, 1
L0009: sete al
L000c: movzx eax, al
L000f: ret
C.<M>b__0_0(Int32)
L0000: test dl, 1
L0003: jne short L0015
L0005: mov eax, edx
L0007: shr eax, 0x1f
L000a: add eax, edx
L000c: sar eax, 1
L000e: sete al
L0011: movzx eax, al
L0014: ret
L0015: xor eax, eax
L0017: ret
{
"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