c1/DragonFly__C1LLVMTypes.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Sat, 01 Sep 2018 00:18:23 +0100
changeset 51 bac3aa0c73ef
parent 38 ce82ecc2ca57
permissions -rw-r--r--
UDIS86: fix `UDIS86Instruction >> branchTarget` to handle indirect branch using memory argument ...such as: jmp 0x0($rdx) In that case, branch target address is not statically known so `nil` is returned. Callers must handle this.

"
    Copyright (C) 2016-now Jan Vrany

    This code is not an open-source (yet). You may use this code
    for your own experiments and projects, given that:

    * all modification to the code will be sent to the
      original author for inclusion in future releases
    * this is not used in any commercial software

    This license is provisional and may (will) change in
    a future.
"
"{ Package: 'jv:dragonfly/c1' }"

"{ NameSpace: DragonFly }"

SharedPool subclass:#C1LLVMTypes
	instanceVariableNames:''
	classVariableNames:'TyInstance TyInstanceFields TyInstanceFieldIndexClass
		TyInstanceFieldIndexSize TyInstanceFieldIndexSpace
		TyInstanceFieldIndexFlags TyInstanceFieldIndexAge
		TyInstanceFieldIndexHashLow TyOBJ TyOBJVec TyInlineCache
		TyInlineCacheIndexFunc TyInlineCacheIndexClass
		TyInlineCacheIndexLineNo TyInlineCachePtr TyOBJFUNC TyOBJFUNCs
		TyMContextFields TyMContextFieldIndexCVars TyMContexts
		TyContextFieldIndexFlags TyContextFieldIndexSenderS
		TyContextFieldIndexHome TyContextFieldIndexReceiver
		TyContextFieldIndexSelector TyContextFieldIndexSearchClass
		TyContextFieldIndexMethod TyContextFieldIndexLineNr
		TyContextFieldIndexRetvalTemp TyContextFieldIndexHandleS
		TyMKREALCONTEXT5 TySSENDSs TyJContexts TyJContextFields
		TyJContextFieldIndexExArg TyJContextFieldIndexExPC
		TyJContextFieldIndexByteCode TyJContextFieldIndexConstPool
		TyJContextFieldIndexAcqrMonitors TyJContextFieldIndexCVars
		TyBContextFieldIndexCVars'
	poolDictionaries:''
	category:'DragonFly-C1'
!

!C1LLVMTypes class methodsFor:'documentation'!

copyright
"
    Copyright (C) 2016-now Jan Vrany

    This code is not an open-source (yet). You may use this code
    for your own experiments and projects, given that:

    * all modification to the code will be sent to the
      original author for inclusion in future releases
    * this is not used in any commercial software

    This license is provisional and may (will) change in
    a future.

"
! !

!C1LLVMTypes class methodsFor:'initialization'!

initialize
    "Invoked at system start or when the class is dynamically loaded."

    "/ please change as required (and remove this comment)

    TyInstance := LLVMType named: '__instance'.
    TyOBJ := TyInstance pointer.
    TyOBJVec := TyOBJ pointer.
    TyInstanceFields := {
        TyOBJ.                      "/ o_class
        LLVMType int32.             "/ o_size
        LLVMType int8.              "/ o_space
        LLVMType int8.              "/ o_flags
        LLVMType int8.              "/ o_age
        LLVMType int8.              "/ o_hashLow
    }.
    TyInstance elementTypes: TyInstanceFields.

    TyInstanceFieldIndexClass := 0.
    TyInstanceFieldIndexSize := 1.
    TyInstanceFieldIndexSpace := 2.
    TyInstanceFieldIndexFlags := 3.
    TyInstanceFieldIndexAge := 4.
    TyInstanceFieldIndexHashLow := 5.

    TyMContextFields := TyInstanceFields , (Context instVarNames collect: [ :nm | nm last == $* ifTrue:[ LLVMType intptr pointer ] ifFalse:[ TyOBJ ] ]).
    TyContextFieldIndexFlags := TyInstanceFields size - 1 + (Context instVarIndexFor: #flags).
    TyContextFieldIndexSenderS  := TyInstanceFields size - 1 + (Context instVarIndexFor: #'sender*').
    TyContextFieldIndexHome  := TyInstanceFields size - 1 + (Context instVarIndexFor: #home).
    TyContextFieldIndexReceiver  := TyInstanceFields size - 1 + (Context instVarIndexFor: #receiver).
    TyContextFieldIndexSelector  := TyInstanceFields size - 1 + (Context instVarIndexFor: #selector).
    TyContextFieldIndexSearchClass  := TyInstanceFields size - 1 + (Context instVarIndexFor: #searchClass).
    TyContextFieldIndexMethod  := TyInstanceFields size - 1 + (Context instVarIndexFor: #method).
    TyContextFieldIndexLineNr  := TyInstanceFields size - 1 + (Context instVarIndexFor: #lineNr).
    TyContextFieldIndexRetvalTemp  := TyInstanceFields size - 1 + (Context instVarIndexFor: #retvalTemp).
    TyContextFieldIndexHandleS := TyInstanceFields size - 1 + (Context instVarIndexFor: #'handle*').
    TyMContextFieldIndexCVars := TyInstanceFields size + Context instSize.

    self assert: Context instSize == BlockContext instSize.
    TyBContextFieldIndexCVars := TyInstanceFields size + Context instSize.

    TyMContexts := #().

    TyJContextFields := TyMContextFields , (JavaContext instVarNames collect: [ :nm | nm last == $* ifTrue:[ LLVMType intptr pointer ] ifFalse:[ TyOBJ ] ]).
    TyJContextFieldIndexExArg := TyInstanceFields size - 1 + (JavaContext instVarIndexFor: #exArg).
    TyJContextFieldIndexExPC := TyInstanceFields size - 1 + (JavaContext instVarIndexFor: #exPC).
    TyJContextFieldIndexByteCode := TyInstanceFields size - 1 + (JavaContext instVarIndexFor: #byteCode).
    TyJContextFieldIndexConstPool := TyInstanceFields size - 1 + (JavaContext instVarIndexFor: #constPool).
    TyJContextFieldIndexAcqrMonitors := TyInstanceFields size - 1 + (JavaContext instVarIndexFor: #acqrMonitors).
    TyJContextFieldIndexCVars := TyInstanceFields size + JavaContext instSize.

    TyJContexts := #().

    TyInlineCache := LLVMType named: 'inlineCache'.
    TyInlineCachePtr := TyInlineCache pointer.
    TyOBJFUNC := LLVMType function: {
        TyOBJ.                      "/ self
        TyOBJ.                      "/ selector
        TyOBJ.                      "/ searchClass or nil
        TyInlineCachePtr .          "/ pIlc
    } varargs: true returning: TyOBJ.

    TyInlineCache elementTypes: {
        TyOBJFUNC pointer .         "/ ilc_func
        TyOBJ.                      "/ ilc_class
        TyInlineCachePtr .          "/ ilc_link
        TyOBJ .                     "/ ilc_lineNo
        LLVMType char pointer .     "/ ilc_poly
    }.
    TyInlineCacheIndexFunc := 0.
    TyInlineCacheIndexClass := 1.
    TyInlineCacheIndexLineNo := 3.

    TyOBJFUNCs := {
        "/ 0 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
        } returning: TyOBJ .
        "/ 1 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ .
        } returning: TyOBJ .
        "/ 2 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 3 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 4 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 5 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 6 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 7 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 8 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 9 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 10 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 11 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 12 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 13 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 14 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 16 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            TyOBJ.                      "/ searchClass or nil
            TyInlineCachePtr .          "/ pIlc
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
    }.

    TyMKREALCONTEXT5 := LLVMType function: { TyOBJ } returning: TyOBJ.

    TySSENDSs := {
        "/ 0 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
        } returning: TyOBJ .
        "/ 1 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ .
        } returning: TyOBJ .
        "/ 2 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 3 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 4 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 5 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 6 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 7 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 8 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 9 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 10 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 11 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 12 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 13 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 14 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
        "/ 16 args
        LLVMType function: {
            TyOBJ.                      "/ self
            TyOBJ.                      "/ selector
            LLVMType int32.             "/ lineNr
            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
        } returning: TyOBJ .
    }.

    "Modified: / 07-08-2016 / 22:27:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!C1LLVMTypes class methodsFor:'accessing'!

tyBContext:size 
    "Return a type for (Smalltalk) block context with given `size`. Size 
     should be numArgs + numVars + numTemps"

    "/ In Smalltalk/X, Context and BlockContext are the same (i.e., have the same
    "/ slots. See BlockContext class. Hence, do the same as for (Smalltalk) method
    "/ context.
    ^ self tyMContext: size

    "Created: / 07-08-2016 / 10:07:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

tyJContext:size 
    "Return a type for Java method context with given `size`. Size 
     should be numArgs + numVars + numTemps. Note, that `long` and
     `double` arguments take two slots, this MUST be reflected in `size`
     parameter (i.e., caller must compute size properly - this method does
     not care).
     "
    
    | tyContext |

    TyJContexts size < (size + 1) ifTrue:[
        | tmp |

        tmp := Array new:size + 1.
        tmp 
            replaceFrom:1
            to:TyJContexts size
            with:TyJContexts.
        TyJContexts := tmp.
    ].
    tyContext := TyJContexts at:size + 1.
    tyContext isNil ifTrue:[
        tyContext := LLVMType named:'__context' , size printString.
        size == 0 ifTrue:[
            tyContext elementTypes:TyJContextFields
        ] ifFalse:[
            tyContext 
                elementTypes:(TyJContextFields copyWith:(LLVMType arrayOf:TyOBJ size:size))
        ].
        TyJContexts at:size + 1 put:tyContext.
    ].
    ^ tyContext

    "
     DragonFly::C1LLVMTypes tyContext: 3"

    "Created: / 07-08-2016 / 10:09:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 07-08-2016 / 22:32:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

tyMContext:size 
    "Return a type for (Smalltalk) method context with given `size`. Size 
     should be numArgs + numVars + numTemps"
    
    | tyContext |

    TyMContexts size < (size + 1) ifTrue:[
        | tmp |

        tmp := Array new:size + 1.
        tmp 
            replaceFrom:1
            to:TyMContexts size
            with:TyMContexts.
        TyMContexts := tmp.
    ].
    tyContext := TyMContexts at:size + 1.
    tyContext isNil ifTrue:[
        tyContext := LLVMType named:'__context' , size printString.
        size == 0 ifTrue:[
            tyContext elementTypes:TyMContextFields
        ] ifFalse:[
            tyContext 
                elementTypes:(TyMContextFields copyWith:(LLVMType arrayOf:TyOBJ size:size))
        ].
        TyMContexts at:size + 1 put:tyContext.
    ].
    ^ tyContext

    "
     DragonFly::C1LLVMTypes tyMContext: 3"

    "Created: / 20-04-2016 / 23:06:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 07-08-2016 / 21:34:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!C1LLVMTypes class methodsFor:'documentation'!

version_HG
    ^ '$Changeset: <not expanded> $'
! !


C1LLVMTypes initialize!