From 7f3a4856ad35cb0713d36911d252f2b8c6d71b39 Mon Sep 17 00:00:00 2001 From: JMLF Date: Fri, 25 Jul 2025 12:08:56 +0200 Subject: [PATCH 1/3] If outerContext is nil we do not return self sender anymore --- src/Kernel-CodeModel/Context.class.st | 4 ++-- src/OpalCompiler-Core/OCBlockScope.class.st | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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/OCBlockScope.class.st b/src/OpalCompiler-Core/OCBlockScope.class.st index ccf9574d4fa..af8e8a782b2 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 ifNil: [ self error: 'OuterContext is not available' ] ] From d230dbb887c7c00324f0149cbbb21151061ab873 Mon Sep 17 00:00:00 2001 From: JMLF Date: Fri, 25 Jul 2025 14:29:36 +0200 Subject: [PATCH 2/3] Tests in MethodMapExample splited between FullBlock and CleanBlock + CleanBlock unreleated test fix --- src/OpalCompiler-Tests/MethodMapExamples.class.st | 8 ++++++++ src/OpalCompiler-Tests/MethodMapTest.class.st | 11 ++++++++++- .../OCContextTempMappingTest.class.st | 4 ++-- 3 files changed, 20 insertions(+), 3 deletions(-) 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 From 50c090f1c42133015cce027045227cd1dfeb9246 Mon Sep 17 00:00:00 2001 From: JMLF Date: Fri, 25 Jul 2025 14:52:21 +0200 Subject: [PATCH 3/3] Raise a better exception with contextual information --- src/OpalCompiler-Core/OCAbstractMethodScope.class.st | 5 ++++- src/OpalCompiler-Core/OCBlockScope.class.st | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) 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 af8e8a782b2..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: [ self error: 'OuterContext is not available' ] + ^ aContext outerContext ]