From e1ec3bcdd229686f6213cbbbbbb8abd26ddcf033 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Thu, 7 Sep 2023 17:06:40 +0200 Subject: [PATCH] More simplifications. Now that exception handlers are outside of the fast path, we can just use a block. --- src/MethodProxies/MpCannotInstall.class.st | 4 +++ src/MethodProxies/MpHiddenSelector.class.st | 7 ++++ src/MethodProxies/MpMethodProxy.class.st | 18 ++++++++-- ...MpProxyInstrumentationDeactivator.class.st | 36 ------------------- 4 files changed, 27 insertions(+), 38 deletions(-) delete mode 100644 src/MethodProxies/MpProxyInstrumentationDeactivator.class.st diff --git a/src/MethodProxies/MpCannotInstall.class.st b/src/MethodProxies/MpCannotInstall.class.st index 9f065d4..5b25ec0 100644 --- a/src/MethodProxies/MpCannotInstall.class.st +++ b/src/MethodProxies/MpCannotInstall.class.st @@ -1,3 +1,7 @@ +" +I'm an exception raised when a proxy cannot be installed. +This usually happens when the wrapped method is a very special method whose instrumentation could break the system. +" Class { #name : #MpCannotInstall, #superclass : #Error, diff --git a/src/MethodProxies/MpHiddenSelector.class.st b/src/MethodProxies/MpHiddenSelector.class.st index 2f32e51..cc01a9e 100644 --- a/src/MethodProxies/MpHiddenSelector.class.st +++ b/src/MethodProxies/MpHiddenSelector.class.st @@ -1,3 +1,10 @@ +" +I represent a selector that is hidden for the user, used to install hidden methods in method dictionaries. +I'm not a string, so I cannot be typed, avoiding potential conflicts. + +I'm used as key of the original method wrapped by proxies, to ensure this wrapped method can be called using myself as selector. +Check my usages during proxy installation. +" Class { #name : #MpHiddenSelector, #superclass : #Object, diff --git a/src/MethodProxies/MpMethodProxy.class.st b/src/MethodProxies/MpMethodProxy.class.st index c633213..699393c 100644 --- a/src/MethodProxies/MpMethodProxy.class.st +++ b/src/MethodProxies/MpMethodProxy.class.st @@ -1157,8 +1157,22 @@ MpMethodProxy >> install [ (proxyMethod hasPragmaNamed: #noInstrumentation) ifTrue: [ ^ MpCannotInstall signalWith: self ]. - deactivator := MpProxyInstrumentationDeactivator new. - deactivator handler: handler. + deactivator := [ "Execution handler for the slow path. An exception or a non local return happened during proxy execution" + | wasMeta trapContext | + + "Jump to the meta level (to avoid meta-recursions) to observe if the handler was in a meta level, marked by the wasMeta flag. + During the meta-jump call the handler to tell there was an unwind. + " + thisProcess shiftLevelUp. + trapContext := thisContext findContextSuchThat: [ :ctx | ctx isUnwindContext ]. + wasMeta := trapContext tempNamed: 'wasMeta'. + handler aboutToReturnWithReceiver: trapContext receiver arguments: trapContext arguments. + thisProcess shiftLevelDown. + + "If the handler was in a meta-state (i.e., the exception or non-local return happened in the handler), shift it back to the base level before returning. + Otherwise, we were already in the base level and we need to do nothing!" + wasMeta ifTrue: [ thisProcess shiftLevelDown ]. + ]. newTrap := self trapMethodPrototype copy. trapSelector := newTrap selector. diff --git a/src/MethodProxies/MpProxyInstrumentationDeactivator.class.st b/src/MethodProxies/MpProxyInstrumentationDeactivator.class.st deleted file mode 100644 index b9c3602..0000000 --- a/src/MethodProxies/MpProxyInstrumentationDeactivator.class.st +++ /dev/null @@ -1,36 +0,0 @@ -Class { - #name : #MpProxyInstrumentationDeactivator, - #superclass : #InstrumentationEnsurer, - #instVars : [ - 'handler' - ], - #category : #MethodProxies -} - -{ #category : #accessing } -MpProxyInstrumentationDeactivator >> handler [ - - ^ handler -] - -{ #category : #accessing } -MpProxyInstrumentationDeactivator >> handler: anObject [ - - handler := anObject -] - -{ #category : #evaluating } -MpProxyInstrumentationDeactivator >> value [ - - - "Slow path, an exception or a non local return happened" - | wasMeta me | - thisProcess shiftLevelUp. - - me := thisContext findContextSuchThat: [ :ctx | ctx isUnwindContext ]. - wasMeta := me tempNamed: 'wasMeta'. - handler aboutToReturnWithReceiver: me receiver arguments: me arguments. - thisProcess shiftLevelDown. - wasMeta ifTrue: [ thisProcess shiftLevelDown ]. - -]