On Jun 27, 2013, at 8:16 AM, Clément Bera <[email protected]> wrote:
> 
> In Pharo 3 we will support conditional optimized messages ( #ifTrue:, 
> #ifFalse:, #ifTrue:ifFalse: and #ifFalse:ifTrue: ) sent on non boolean 
> receiver. However, this feature will be slow, so one should not use it too 
> much (as #become:, #isKindOf:, ...). Basically Opal compiles on the fly 
> without optimizing it the conditional messageNode as a DoIt, run it, and jump 
> in the context to the pc corresponding to the next ast node. We don't 
> generate extra bytecode as you suggested, because it will grow the size of 
> the image a lot and slow down the system with extra conditions.
> 

It's actually not a lot of code. We need to debug/fix it for all the cases, 
though, this might add some more complexity:

mustBeBooleanInMagic: context
        "Permits to redefine methods inlined by compiler.
        Take the ast node corresponding to the mustBeBoolean error, compile it 
on the fly with Opal and executes it as a DoIt. Then resume the execution of 
the context."

        | proceedValue sendNode selector expression  arguments methodNode 
method offset position |
        context skipBackBeforeJump.
        
        sendNode := context sourceNode sourceNodeForPC: context pc.
        position := sendNode irInstruction bytecodeOffset.
        offset :=  sendNode irInstruction nextBytecodeOffsetAfterJump - 
position.
        
        expression := sendNode  copy asSequenceNode transformLastToReturn.
        selector :=  #ExecuteUnOptimzedIn:. arguments := {(RBVariableNode 
named:'ThisContext')}.
        methodNode := RBMethodNode selector: selector arguments: arguments 
body: expression.
        
        context tempNames do: [:tempName |
                 methodNode :=methodNode rewriteTempNamedWrite: tempName 
forContext: context.
                 methodNode :=methodNode rewriteTempNamedRead: tempName 
forContext: context.
        ].
        methodNode compilationContext: sendNode methodNode compilationContext.
        methodNode compilationContext 
                class: UndefinedObject;
                compilerOptions: #(+ optIlineNone).     
        
        method := methodNode generateWithSource.
        
        context jump: offset.
        
        proceedValue  := self withArgs: {context} executeMethod: method.
        ^proceedValue


Reply via email to