Skip to content

Add support for generic types and methods#41

Open
RedworkDE wants to merge 7 commits intoEgorBo:mainfrom
RedworkDE:generics-support
Open

Add support for generic types and methods#41
RedworkDE wants to merge 7 commits intoEgorBo:mainfrom
RedworkDE:generics-support

Conversation

@RedworkDE
Copy link

Adds a setting to provide types to use for generic arguments.

Example:

static T[] NewArray<T>()
{
	return new T[5];
}

produces the output

; Assembly listing for method Program2:NewArray[System.__Canon]():<unnamed>
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; Final local variable assignments
;
;  V00 TypeCtx      [V00,T00] (  5,  4.25)    long  ->  rcx         single-def
;  V01 OutArgs      [V01    ] (  1,  1   )  lclBlk (32) [rsp+00H]   "OutgoingArgSpace"
;  V02 tmp1         [V02,T01] (  3,  3   )    long  ->  rdx         "spilling Runtime Lookup tree"
;  V03 cse0         [V03,T02] (  3,  2.25)    long  ->  rdx         "CSE - aggressive"
;
; Lcl frame size = 40

G_M13538_IG01:              ;; offset=0000H
       4883EC28             sub      rsp, 40
       48894C2420           mov      qword ptr [rsp+20H], rcx
						;; size=9 bbWeight=1    PerfScore 1.25
G_M13538_IG02:              ;; offset=0009H
       488B5138             mov      rdx, qword ptr [rcx+38H]
       488B5210             mov      rdx, qword ptr [rdx+10H]
       4885D2               test     rdx, rdx
       7402                 je       SHORT G_M13538_IG04
						;; size=13 bbWeight=1    PerfScore 5.25
G_M13538_IG03:              ;; offset=0016H
       EB12                 jmp      SHORT G_M13538_IG05
						;; size=2 bbWeight=0.25 PerfScore 0.50
G_M13538_IG04:              ;; offset=0018H
       48BA905DC4D6F77F0000 mov      rdx, 0x7FF7D6C45D90      ; global ptr
       E899F9505F           call     CORINFO_HELP_RUNTIMEHANDLE_METHOD
       488BD0               mov      rdx, rax
						;; size=18 bbWeight=0.25 PerfScore 0.38
G_M13538_IG05:              ;; offset=002AH
       488BCA               mov      rcx, rdx
       BA05000000           mov      edx, 5
       E809F7875F           call     CORINFO_HELP_NEWARR_1_OBJ
       90                   nop      
						;; size=14 bbWeight=1    PerfScore 1.75
G_M13538_IG06:              ;; offset=0038H
       4883C428             add      rsp, 40
       C3                   ret      
						;; size=5 bbWeight=1    PerfScore 1.25

; Total bytes of code 61, prolog size 9, PerfScore 16.48, instruction count 16, allocated bytes for code 61 (MethodHash=f226cb1d) for method Program2:NewArray[System.__Canon]():<unnamed>
; ============================================================

; Assembly listing for method Program2:NewArray[int]():<unnamed>
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; Final local variable assignments
;
;  V00 OutArgs      [V00    ] (  1,  1   )  lclBlk (32) [rsp+00H]   "OutgoingArgSpace"
;
; Lcl frame size = 40

G_M25943_IG01:              ;; offset=0000H
       4883EC28             sub      rsp, 40
						;; size=4 bbWeight=1    PerfScore 0.25
G_M25943_IG02:              ;; offset=0004H
       48B978D05FD6F77F0000 mov      rcx, 0x7FF7D65FD078      ; <unnamed>
       BA05000000           mov      edx, 5
       E868F6875F           call     CORINFO_HELP_NEWARR_1_VC
       90                   nop      
						;; size=21 bbWeight=1    PerfScore 1.75
G_M25943_IG03:              ;; offset=0019H
       4883C428             add      rsp, 40
       C3                   ret      
						;; size=5 bbWeight=1    PerfScore 1.25

; Total bytes of code 30, prolog size 4, PerfScore 6.25, instruction count 7, allocated bytes for code 30 (MethodHash=e37a9aa8) for method Program2:NewArray[int]():<unnamed>
; ============================================================

The default setting is to try int and Tuple<object, int> for all arguments, because common value type and some reference type. Exact reference type doesn't matter anyways and this way it demonstrates the syntax for specifying generic arguments.
For completeness, I added a way to specify pointer and array types, but I don't think there is a way for them to matter, so they are not documented in the UI.

@EgorBo
Copy link
Owner

EgorBo commented Feb 10, 2023

@RedworkDE oops, just noticed your PR, thank you so much for the contribution!

It slightly not aligned to the way I see generics support - I want to avoid complex UI for them and give user ability to quickly declare generics via comments directly in code, e.g.:

// Disasmo-Generic: int, System.String
// Disasmo-Generic: byte, float
static void Foo<T1, T2>()
{

}

this is expected to produce two compilations: Foo<int, System._Canon> and Foo<byte, float>

If user attempts to disasm a function without these annotations - a quick tutorial is printed in the output.

@RedworkDE
Copy link
Author

I'll have to think about how to best get data from such a format into the loader; I imagine there will be some complications with correctly matching things in all cases, tho I think it would be easiest to reuse the loader that i currently have and to just live with a few extra instantiations if you reuse the generic parameter name in type and method / disassemble the whole type.

I'll see what works without becoming a giant mess and taking too much time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants