RegressionTests__CompilerTests2.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 24 Jun 2013 16:34:45 +0200
changeset 948 a28d3cfb7c43
parent 930 78e2acffdea6
child 988 cd49b35f671f
permissions -rw-r--r--
Added test from global variable access when compiling from within the workspace.

"{ Package: 'exept:regression' }"

"{ NameSpace: RegressionTests }"

TestCase subclass:#CompilerTests2
	instanceVariableNames:'methods enabledJIT'
	classVariableNames:''
	poolDictionaries:''
	category:'tests-Regression'
!


!CompilerTests2 methodsFor:'private'!

assertSendersMethodIsIdenticalTo: sendersMethod
    "Do not assert here, pass down to have some immediate, possibly lazy contexts
     in between"

    self assertSendersSendersMethodIsIdenticalTo: sendersMethod

    "Created: / 25-04-2013 / 15:28:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

assertSendersSendersMethodIsIdenticalTo: thisMethod
    | ctx m |

    ctx := thisContext sender sender.
    "/ Now, DO NOT USE Context>>method as it searches for the method
    "/ if it is not set!!

    m := ctx instVarAt: (Context instVarIndexFor: #method).
    self assert: m == thisMethod

    "Created: / 25-04-2013 / 15:30:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

compile: source mode: mode
    "Compile given source and returns the new method.
     The from the source is prepended the mode + underscore
     (i.e., foo -> stc_foo).

     If mode is:
       #stc....then the method is stc-compiled.
       #jit....then the method is bytecode compiled and left
               to the jitter
       #bc.....them the method is bytecode compiled and marked
               as checked so JIT won't even try.
    "

    | m |

    Class withoutUpdatingChangesDo:[
        mode == #stc ifTrue:[
            ParserFlags withSTCCompilation:#always do:[
                m := self class compile: (mode, '_', source) classified: 'private - *dynamic*'.
            ].
        ] ifFalse:[
            ParserFlags withSTCCompilation:#never do:[
                m := self class compile: (mode, '_', source) classified: 'private - *dynamic*'.
                m checked: (mode == #bc)
            ].
        ].
    ].
    methods add: m.
    ^m

    "Created: / 25-04-2013 / 15:18:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

currentLineNumber
    thisContext fixAllLineNumbers.
    ^thisContext sender lineNumber.

    "Created: / 12-04-2013 / 21:20:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 13-04-2013 / 10:12:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 methodsFor:'private-mock methods'!

method_lineno_002
    1 factorial. ^self currentLineNumber

    "Created: / 12-04-2013 / 21:22:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

method_lineno_300
    "DO NOT MAKE THIS METHOD SHORTER, DO NOT REMOVE BLANK LINES!!!!!!"









































































































































































































































































































    ^self currentLineNumber

    "Created: / 12-04-2013 / 21:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

method_methodslot_01: thisMethod
    self assertSendersMethodIsIdenticalTo: thisMethod

    "Created: / 25-04-2013 / 15:28:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

method_methodslot_02: thisMethod
     [ self assertSendersMethodIsIdenticalTo: thisMethod ]
        valueWithArguments:#() "/ don't use #value, it gets optimized!!

    "Created: / 25-04-2013 / 15:36:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

method_methodslot_03: thisMethod
    "Deep block nesting...."
    [
        [
            [
                [ 
                    self assertSendersMethodIsIdenticalTo: thisMethod 
                ] valueWithArguments:#() "/ don't use #value, it gets optimized!!
            ] valueWithArguments:#() "/ don't use #value, it gets optimized!!
        ] valueWithArguments:#() "/ don't use #value, it gets optimized!!
    ] valueWithArguments:#() "/ don't use #value, it gets optimized!!

    "Created: / 25-04-2013 / 15:38:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 methodsFor:'setup'!

setUp
    methods := Set new.
    enabledJIT := ObjectMemory justInTimeCompilation:true.

    "Created: / 25-04-2013 / 15:20:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

tearDown
    ObjectMemory justInTimeCompilation: enabledJIT.
    Class withoutUpdatingChangesDo:[
        | classesToRemove |
        (Smalltalk at: #'exept_regression_testData_CompilerTests2') notNil ifTrue:[
            (Smalltalk at: #'exept_regression_testData_CompilerTests2') classes do:[:e|
                e notNil ifTrue:[
                    Smalltalk removeClass: e
                ].
            ].
        ].
        Smalltalk allClassesDo:[:cls|
            (#(
                'exept:regression/testData/CompilerTests2'
                "/Add more...
            ) includes: cls package) ifTrue:[
                Smalltalk removeClass: cls
            ]
        ].

        methods do:[:m|
            m mclass removeSelector: m selector.
        ]
    ]

    "Created: / 26-10-2012 / 11:32:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 24-06-2013 / 14:12:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 methodsFor:'tests'!

test_01
    "JV@2012-10-26:

     When a package is loaded from source using

        Smalltalk loadPackage:'...'

     expression __EVALUATED FROM WORKSPACE__ AND a method from loaded class
     uses a class from the same package that is not yet loaded (i.e., it will
     be loaded later),

     then the compiler as of 2012-10-26 generates access to a workspace variable
     instead of access to a global

     This tests checks for this bug
    "

    | ws |

    "/ this test only works with a Display...
    self skipIf:[Display isNil] description:'Test requires a Display'.

    "/First, make sure that package is not yet loaded...
    self
        assert: (Smalltalk at: #'exept_regression_testData_CompilerTests2') isNil
        description: 'Mock package already loaded'.

    ws := WorkspaceApplication new.
    ws selectedWorkspace
        autoDefineVariables: #workspace;
        contents: '(Smalltalk loadPackage: #''exept:regression/testData/CompilerTests2'')';
        selectAll;
        doIt.

    self assert: (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') new foo class
                    == (Smalltalk at: #'RegressionTests::CompilerTests2Mock2')

    "Created: / 26-10-2012 / 11:59:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 24-06-2013 / 15:30:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_02
    "JV@2012-10-26:

     When a package is loaded from source using

	Smalltalk loadPackage:'...'

     expression and a method from loaded class in namespace uses a class from the
     same package and same namespace, that is not yet loaded (i.e., it will be loaded
     later),

     then the compiler as of 2012-10-26 generates access to class in no namespace.

     This test checks for this bug
    "

    "/First, make sure that package is not yet loaded...
    self
	assert: (Smalltalk at: #'exept_regression_estData_CompilerTests2') isNil
	description: 'Mock package already loaded'.

    self
	assert: (Smalltalk loadPackage: #'exept:regression/testData/CompilerTests2')
	description: 'Cannot load mock package!!'.


    self assert: (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') new foo class
		    == (Smalltalk at: #'RegressionTests::CompilerTests2Mock2')

    "Created: / 26-10-2012 / 12:26:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (comment): / 12-02-2013 / 16:24:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_03
    "JV@2012-10-26:

     When a method is compiled programmaticallu from
     __FROM WORKSPACE__ AND a method uses a class that is not yet loaded,
     then the compiler as of 2013-06-24 generates access to a workspace variable
     instead of access to a global

     This tests checks for this bug
    "

    | ws m1 m2 |

    "/ this test only works with a Display...
    self skipIf:[Display isNil] description:'Test requires a Display'.

    "/First, make sure that package is not yet loaded...
    self
        assert: (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') isNil
        description: 'RegressionTests::CompilerTests2Mock1 already loaded'.

    Smalltalk fileIn:'RegressionTests__CompilerTests2Mock1.st' inPackage:#'exept:regression/testData/CompilerTests2'.

    self
        assert: (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') notNil
        description: 'RegressionTests::CompilerTests2Mock1 failed to load'.


    ws := WorkspaceApplication new.
    ws selectedWorkspace 
        autoDefineVariables: #workspace;
        contents: 'RegressionTests::CompilerTests2Mock1 recompile';
        selectAll;
        doIt.

    m1 := (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') compiledMethodAt: #foo.
    m2 := (Smalltalk at: #'RegressionTests::CompilerTests2Mock1') compiledMethodAt: #bar.

    self assert: (m1 literals allSatisfy:[:e|e class ~~ ValueHolder]).
    self assert: (m2 literals allSatisfy:[:e|e class ~~ ValueHolder]).

    "Created: / 24-06-2013 / 14:06:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified (comment): / 24-06-2013 / 15:33:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 methodsFor:'tests - line numbers'!

test_lineno_01_bci
    | m002 m300 l |

    m002 := self compile: (self class >> #method_lineno_002) source mode: #bc.
    m300 := self compile: (self class >> #method_lineno_300) source mode: #bc.

    self assert: (l := self bc_method_lineno_002) == 2.
    self assert: (l := self bc_method_lineno_300) == 300.

    self assert: m002 code isNil.
    self assert: m300 code isNil.

    "Created: / 12-04-2013 / 21:24:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 25-04-2013 / 15:24:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_lineno_01_jit
    | m002 m300 l |

    m002 := self compile: (self class >> #method_lineno_002) source mode: #jit.
    m300 := self compile: (self class >> #method_lineno_300) source mode: #jit.

    self assert: (l := self jit_method_lineno_002) == 2.
    self assert: (l := self jit_method_lineno_300) == 300.

    self assert: m002 code notNil.
    self assert: m300 code notNil.

    "Created: / 12-04-2013 / 21:41:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 10-05-2013 / 18:23:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_lineno_01_stc
    | m002 m300 l |

    m002 := self class >> #method_lineno_002.
    m300 := self class >> #method_lineno_300.

    self compile: m002 source mode: #stc.
    self compile: m300 source mode: #stc.

    self assert: (l := self stc_method_lineno_002) == 2.
    self assert: (l := self stc_method_lineno_300) == 300.

    "Created: / 12-04-2013 / 21:50:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 25-04-2013 / 15:22:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 methodsFor:'tests - method slot'!

test_methodslot_01_bci
    | m |

    m := self compile: (self class >> #method_methodslot_01:) source mode: #bc.
    self bc_method_methodslot_01: m.
    self assert: m code isNil.

    "Created: / 25-04-2013 / 15:33:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_01_jit
    | m |

    m := self compile: (self class >> #method_methodslot_01:) source mode: #jit.
    self jit_method_methodslot_01: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:34:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_01_stc
    | m |

    m := self compile: (self class >> #method_methodslot_01:) source mode: #stc.
    self stc_method_methodslot_01: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:34:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_02_bci
    | m |

    m := self compile: (self class >> #method_methodslot_02:) source mode: #bc.
    self bc_method_methodslot_02: m.
    self assert: m code isNil.

    "Created: / 25-04-2013 / 15:36:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_02_jit
    | m |

    m := self compile: (self class >> #method_methodslot_02:) source mode: #jit.
    self jit_method_methodslot_02: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:37:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_02_stc
    | m |

    m := self compile: (self class >> #method_methodslot_02:) source mode: #stc.
    self stc_method_methodslot_02: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_03_bci
    | m |

    m := self compile: (self class >> #method_methodslot_03:) source mode: #bc.
    self bc_method_methodslot_03: m.
    self assert: m code isNil.

    "Created: / 25-04-2013 / 15:39:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_03_jit
    | m |

    m := self compile: (self class >> #method_methodslot_03:) source mode: #jit.
    self jit_method_methodslot_03: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:39:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

test_methodslot_03_stc
    | m |

    m := self compile: (self class >> #method_methodslot_03:) source mode: #stc.
    self stc_method_methodslot_03: m.
    self assert: m code notNil.

    "Created: / 25-04-2013 / 15:39:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!CompilerTests2 class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
!

version_SVN
    ^ '$Id$'
! !