diff --git a/src/Kernel-CodeModel/Context.class.st b/src/Kernel-CodeModel/Context.class.st index ca52a6d07aa..a0b66d66e44 100644 --- a/src/Kernel-CodeModel/Context.class.st +++ b/src/Kernel-CodeModel/Context.class.st @@ -1244,9 +1244,9 @@ Context >> objectSize: anObject [ { #category : 'accessing' } Context >> outerContext [ "Answer the context within which the receiver is nested." + - ^closureOrNil ifNotNil: - [closureOrNil outerContext ifNil: ["if the outer is nil, this is a CleanBlock" self sender]] + ^ closureOrNil ifNotNil: [ closureOrNil outerContext ] ] { #category : 'accessing' } diff --git a/src/OpalCompiler-Core/OCAbstractMethodScope.class.st b/src/OpalCompiler-Core/OCAbstractMethodScope.class.st index a1c48be1fa1..4188ddae09c 100644 --- a/src/OpalCompiler-Core/OCAbstractMethodScope.class.st +++ b/src/OpalCompiler-Core/OCAbstractMethodScope.class.st @@ -143,8 +143,11 @@ OCAbstractMethodScope >> localTemps [ OCAbstractMethodScope >> lookupDefiningContextForVariable: var startingFrom: aContext [ "Is this the definition context for var? If it not, we look in the outer context using the corresponding outer scope. If found, we return the context" + | nextContext | + nextContext := self nextOuterScopeContextOf: aContext. + nextContext ifNil: [ self error: var name, ' optimized out' ]. ^self = var scope - ifFalse: [ self outerScope lookupDefiningContextForVariable: var startingFrom: (self nextOuterScopeContextOf: aContext) ] + ifFalse: [ self outerScope lookupDefiningContextForVariable: var startingFrom: nextContext ] ifTrue: [ aContext ] ] diff --git a/src/OpalCompiler-Core/OCBlockScope.class.st b/src/OpalCompiler-Core/OCBlockScope.class.st index ccf9574d4fa..8f643bb3ae1 100644 --- a/src/OpalCompiler-Core/OCBlockScope.class.st +++ b/src/OpalCompiler-Core/OCBlockScope.class.st @@ -41,5 +41,5 @@ OCBlockScope >> nextOuterScopeContextOf: aContext [ "Returns the next context to lookup a variable name from within outer scope. If it is block context then we return outer context for lookup. But if it is method context lookup will continue in same context but within outer scope" - ^ aContext outerContext ifNil: [ aContext ] + ^ aContext outerContext ] diff --git a/src/OpalCompiler-Tests/MethodMapExamples.class.st b/src/OpalCompiler-Tests/MethodMapExamples.class.st index f7c797b71e0..297322632d0 100644 --- a/src/OpalCompiler-Tests/MethodMapExamples.class.st +++ b/src/OpalCompiler-Tests/MethodMapExamples.class.st @@ -24,6 +24,14 @@ MethodMapExamples >> exampleAccessOuterFromCleanBlock [ ^[ thisContext tempNamed: 'b' ] value ] +{ #category : 'examples' } +MethodMapExamples >> exampleAccessOuterFromFullBlock [ + + | b | + b := 1. + ^[ thisContext tempNamed: 'b' ] value +] + { #category : 'examples' } MethodMapExamples >> exampleConstantBlock [ diff --git a/src/OpalCompiler-Tests/MethodMapTest.class.st b/src/OpalCompiler-Tests/MethodMapTest.class.st index 2a82dad6cd8..2efa8290d30 100644 --- a/src/OpalCompiler-Tests/MethodMapTest.class.st +++ b/src/OpalCompiler-Tests/MethodMapTest.class.st @@ -113,7 +113,16 @@ MethodMapTest >> testDeadContextSourceNode [ { #category : 'tests - temp access' } MethodMapTest >> testExampleAccessOuterFromCleanBlock [ - self assert: (self compileAndRunExample: #exampleAccessOuterFromCleanBlock) equals: 1 +"Should rise an exception since we are trying to access outerContext from a clean block" + self should: [(self compileAndRunExample: #exampleAccessOuterFromCleanBlock)] raise: Exception. + +] + +{ #category : 'tests - temp access' } +MethodMapTest >> testExampleAccessOuterFromFullBLock [ + + self assert: (self compileAndRunExample: #exampleAccessOuterFromFullBlock) equals: 1 + ] { #category : 'tests - temp access' } diff --git a/src/OpalCompiler-Tests/OCContextTempMappingTest.class.st b/src/OpalCompiler-Tests/OCContextTempMappingTest.class.st index a77b209e4a9..04d924fd56a 100644 --- a/src/OpalCompiler-Tests/OCContextTempMappingTest.class.st +++ b/src/OpalCompiler-Tests/OCContextTempMappingTest.class.st @@ -33,7 +33,7 @@ OCContextTempMappingTest >> fetchArgFromOptimizedBlockInsideFullBlock: anArg ext { #category : 'tests' } OCContextTempMappingTest >> testAccessingArgOfOuterBlockFromAnotherDeepBlock [ - + | actual | "Check the source code availability to do not fail on images without sources" @@ -41,7 +41,7 @@ OCContextTempMappingTest >> testAccessingArgOfOuterBlockFromAnotherDeepBlock [ actual := [:outerArg | outerArg asString. - [ :innerArg | innerArg asString. thisContext tempNamed: #outerArg ] value: #innerValue. + [ :innerArg | innerArg asString.thisContext tempNamed: #outerArg ] value: #innerValue. ] value: #outerValue. self assert: actual equals: #outerValue