The Trunk: Compiler-ar.108.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Compiler-ar.108.mcz

commits-2
Andreas Raab uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-ar.108.mcz

==================== Summary ====================

Name: Compiler-ar.108
Author: ar
Time: 22 December 2009, 12:48:23 pm
UUID: 538bb76e-8967-e445-9b2c-161c98c289d6
Ancestors: Compiler-ar.107

CompiledMethodTrailer phase 2.

=============== Diff against Compiler-ar.107 ===============

Item was changed:
  ----- Method: Compiler>>compiledMethodFor:in:to:notifying:ifFail:logged: (in category 'public access') -----
  compiledMethodFor: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
  "Compiles the sourceStream into a parse tree, then generates code
  into a method, and answers it.  If receiver is not nil, then the text can
  refer to instance variables of that receiver (the Inspector uses this).
  If aContext is not nil, the text can refer to temporaries in that context
  (the Debugger uses this). If aRequestor is not nil, then it will receive a
  notify:at: message before the attempt to evaluate is aborted."
 
  | methodNode method |
  class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
  self from: textOrStream class: class context: aContext notifying: aRequestor.
  methodNode := self translate: sourceStream noPattern: true ifFail: [^failBlock value].
+ method := self interactive ifTrue: [ methodNode generateWithTempNames ]
+ ifFalse: [methodNode generate].
+
- method := methodNode generate: #(0 0 0 0).
- self interactive ifTrue:
- [method := method copyWithTempsFromMethodNode: methodNode].
  logFlag ifTrue:
  [SystemChangeNotifier uniqueInstance evaluated: sourceStream contents context: aContext].
  ^method!

Item was changed:
  ----- Method: Compiler>>evaluate:in:to:notifying:ifFail:logged: (in category 'public access') -----
  evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
  "Compiles the sourceStream into a parse tree, then generates code into a
  method. This method is then installed in the receiver's class so that it
  can be invoked. In other words, if receiver is not nil, then the text can
  refer to instance variables of that receiver (the Inspector uses this). If
  aContext is not nil, the text can refer to temporaries in that context (the
  Debugger uses this). If aRequestor is not nil, then it will receive a
  notify:at: message before the attempt to evaluate is aborted. Finally, the
  compiled method is invoked from here as DoIt or (in the case of
  evaluation in aContext) DoItIn:. The method is subsequently removed
  from the class, but this will not get done if the invocation causes an
  error which is terminated. Such garbage can be removed by executing:
  Smalltalk allBehaviorsDo: [:cl | cl removeSelector: #DoIt; removeSelector:
  #DoItIn:]."
 
  | methodNode method value toLog itsSelection itsSelectionString |
  class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
  self from: textOrStream class: class context: aContext notifying: aRequestor.
  methodNode := self translate: sourceStream noPattern: true ifFail:
  [^failBlock value].
+
+ method := self interactive ifTrue: [ methodNode generateWithTempNames ]
+ ifFalse: [methodNode generate].
- method := methodNode generate: #(0 0 0 0).
- self interactive ifTrue:
- [method := method copyWithTempsFromMethodNode: methodNode].
 
  value := receiver
  withArgs: (context ifNil: [#()] ifNotNil: [{context}])
  executeMethod: method.
 
  logFlag ifTrue:[
  toLog := ((requestor respondsTo: #selection)  
  and:[(itsSelection := requestor selection) notNil
  and:[(itsSelectionString := itsSelection asString) isEmptyOrNil not]])
  ifTrue:[itsSelectionString]
  ifFalse:[sourceStream contents].
  SystemChangeNotifier uniqueInstance evaluated: toLog context: aContext].
  ^ value!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Nicolas Cellier
Why does this depend on interactive ?

       method := self interactive ifTrue: [    methodNode
generateWithTempNames ]
               ifFalse: [methodNode generate].

Nicolas

2009/12/22  <[hidden email]>:

> Andreas Raab uploaded a new version of Compiler to project The Trunk:
> http://source.squeak.org/trunk/Compiler-ar.108.mcz
>
> ==================== Summary ====================
>
> Name: Compiler-ar.108
> Author: ar
> Time: 22 December 2009, 12:48:23 pm
> UUID: 538bb76e-8967-e445-9b2c-161c98c289d6
> Ancestors: Compiler-ar.107
>
> CompiledMethodTrailer phase 2.
>
> =============== Diff against Compiler-ar.107 ===============
>
> Item was changed:
>  ----- Method: Compiler>>compiledMethodFor:in:to:notifying:ifFail:logged: (in category 'public access') -----
>  compiledMethodFor: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>        "Compiles the sourceStream into a parse tree, then generates code
>         into a method, and answers it.  If receiver is not nil, then the text can
>         refer to instance variables of that receiver (the Inspector uses this).
>         If aContext is not nil, the text can refer to temporaries in that context
>         (the Debugger uses this). If aRequestor is not nil, then it will receive a
>         notify:at: message before the attempt to evaluate is aborted."
>
>        | methodNode method |
>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>        methodNode := self translate: sourceStream noPattern: true ifFail: [^failBlock value].
> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
> +               ifFalse: [methodNode generate].
> +
> -       method := methodNode generate: #(0 0 0 0).
> -       self interactive ifTrue:
> -               [method := method copyWithTempsFromMethodNode: methodNode].
>        logFlag ifTrue:
>                [SystemChangeNotifier uniqueInstance evaluated: sourceStream contents context: aContext].
>        ^method!
>
> Item was changed:
>  ----- Method: Compiler>>evaluate:in:to:notifying:ifFail:logged: (in category 'public access') -----
>  evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>        "Compiles the sourceStream into a parse tree, then generates code into a
>        method. This method is then installed in the receiver's class so that it
>        can be invoked. In other words, if receiver is not nil, then the text can
>        refer to instance variables of that receiver (the Inspector uses this). If
>        aContext is not nil, the text can refer to temporaries in that context (the
>        Debugger uses this). If aRequestor is not nil, then it will receive a
>        notify:at: message before the attempt to evaluate is aborted. Finally, the
>        compiled method is invoked from here as DoIt or (in the case of
>        evaluation in aContext) DoItIn:. The method is subsequently removed
>        from the class, but this will not get done if the invocation causes an
>        error which is terminated. Such garbage can be removed by executing:
>        Smalltalk allBehaviorsDo: [:cl | cl removeSelector: #DoIt; removeSelector:
>        #DoItIn:]."
>
>        | methodNode method value toLog itsSelection itsSelectionString |
>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>        methodNode := self translate: sourceStream noPattern: true ifFail:
>                [^failBlock value].
> +
> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
> +               ifFalse: [methodNode generate].
> -       method := methodNode generate: #(0 0 0 0).
> -       self interactive ifTrue:
> -               [method := method copyWithTempsFromMethodNode: methodNode].
>
>        value := receiver
>                                withArgs: (context ifNil: [#()] ifNotNil: [{context}])
>                                executeMethod: method.
>
>        logFlag ifTrue:[
>                toLog := ((requestor respondsTo: #selection)
>                        and:[(itsSelection := requestor selection) notNil
>                        and:[(itsSelectionString := itsSelection asString) isEmptyOrNil not]])
>                                ifTrue:[itsSelectionString]
>                                ifFalse:[sourceStream contents].
>                SystemChangeNotifier uniqueInstance evaluated: toLog context: aContext].
>        ^ value!
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Igor Stasenko
2009/12/22 Nicolas Cellier <[hidden email]>:
> Why does this depend on interactive ?
>
>       method := self interactive ifTrue: [    methodNode
> generateWithTempNames ]
>               ifFalse: [methodNode generate].
>

who knows :)

i just changed this code to use more convenient forms, but not changed
semantics.

(it is now more readable, up to the point that you start asking questions)  :)


> Nicolas
>
> 2009/12/22  <[hidden email]>:
>> Andreas Raab uploaded a new version of Compiler to project The Trunk:
>> http://source.squeak.org/trunk/Compiler-ar.108.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Compiler-ar.108
>> Author: ar
>> Time: 22 December 2009, 12:48:23 pm
>> UUID: 538bb76e-8967-e445-9b2c-161c98c289d6
>> Ancestors: Compiler-ar.107
>>
>> CompiledMethodTrailer phase 2.
>>
>> =============== Diff against Compiler-ar.107 ===============
>>
>> Item was changed:
>>  ----- Method: Compiler>>compiledMethodFor:in:to:notifying:ifFail:logged: (in category 'public access') -----
>>  compiledMethodFor: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>>        "Compiles the sourceStream into a parse tree, then generates code
>>         into a method, and answers it.  If receiver is not nil, then the text can
>>         refer to instance variables of that receiver (the Inspector uses this).
>>         If aContext is not nil, the text can refer to temporaries in that context
>>         (the Debugger uses this). If aRequestor is not nil, then it will receive a
>>         notify:at: message before the attempt to evaluate is aborted."
>>
>>        | methodNode method |
>>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>>        methodNode := self translate: sourceStream noPattern: true ifFail: [^failBlock value].
>> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
>> +               ifFalse: [methodNode generate].
>> +
>> -       method := methodNode generate: #(0 0 0 0).
>> -       self interactive ifTrue:
>> -               [method := method copyWithTempsFromMethodNode: methodNode].
>>        logFlag ifTrue:
>>                [SystemChangeNotifier uniqueInstance evaluated: sourceStream contents context: aContext].
>>        ^method!
>>
>> Item was changed:
>>  ----- Method: Compiler>>evaluate:in:to:notifying:ifFail:logged: (in category 'public access') -----
>>  evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>>        "Compiles the sourceStream into a parse tree, then generates code into a
>>        method. This method is then installed in the receiver's class so that it
>>        can be invoked. In other words, if receiver is not nil, then the text can
>>        refer to instance variables of that receiver (the Inspector uses this). If
>>        aContext is not nil, the text can refer to temporaries in that context (the
>>        Debugger uses this). If aRequestor is not nil, then it will receive a
>>        notify:at: message before the attempt to evaluate is aborted. Finally, the
>>        compiled method is invoked from here as DoIt or (in the case of
>>        evaluation in aContext) DoItIn:. The method is subsequently removed
>>        from the class, but this will not get done if the invocation causes an
>>        error which is terminated. Such garbage can be removed by executing:
>>        Smalltalk allBehaviorsDo: [:cl | cl removeSelector: #DoIt; removeSelector:
>>        #DoItIn:]."
>>
>>        | methodNode method value toLog itsSelection itsSelectionString |
>>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>>        methodNode := self translate: sourceStream noPattern: true ifFail:
>>                [^failBlock value].
>> +
>> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
>> +               ifFalse: [methodNode generate].
>> -       method := methodNode generate: #(0 0 0 0).
>> -       self interactive ifTrue:
>> -               [method := method copyWithTempsFromMethodNode: methodNode].
>>
>>        value := receiver
>>                                withArgs: (context ifNil: [#()] ifNotNil: [{context}])
>>                                executeMethod: method.
>>
>>        logFlag ifTrue:[
>>                toLog := ((requestor respondsTo: #selection)
>>                        and:[(itsSelection := requestor selection) notNil
>>                        and:[(itsSelectionString := itsSelection asString) isEmptyOrNil not]])
>>                                ifTrue:[itsSelectionString]
>>                                ifFalse:[sourceStream contents].
>>                SystemChangeNotifier uniqueInstance evaluated: toLog context: aContext].
>>        ^ value!
>>
>>
>>
>
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Randal L. Schwartz
>>>>> "Igor" == Igor Stasenko <[hidden email]> writes:

Igor> 2009/12/22 Nicolas Cellier <[hidden email]>:
>> Why does this depend on interactive ?
>>
>>       method := self interactive ifTrue: [    methodNode
>> generateWithTempNames ]
>>               ifFalse: [methodNode generate].
>>

Igor> who knows :)

Igor> i just changed this code to use more convenient forms, but not changed
Igor> semantics.

Igor> (it is now more readable, up to the point that you start asking questions)  :)

Maybe totally unrelated, but is it related to the fact that if you hold
(held?) down the option key (control key?) when you view a method source, it
was decompiled rather than pulling up the actual source?

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Eliot Miranda-2
In reply to this post by Nicolas Cellier


On Tue, Dec 22, 2009 at 5:41 AM, Nicolas Cellier <[hidden email]> wrote:
Why does this depend on interactive ?

      method := self interactive ifTrue: [    methodNode
generateWithTempNames ]
              ifFalse: [methodNode generate].

Nicolas



The assumption is that one wants temp names preserved in doits, but is not particularly interested in temp names in automatic compiles.  Essentially the system is in two modes.  One, with source, does not preserve temp names except for doits because the temp names are in the sources files.  The other, without sources, converts all methods to sourceless with encoded temp names.  But this isn't yet reflected in the code.  The code would better read something like

      method := (self interactive or: [self noSourcesFiles])
                      ifTrue: [methodNode generateWithTempNames]
                      ifFalse: [methodNode generate]

and of course (self interactive or: [self noSourcesFiles]) could be extracted into e.g. a class-side method on CompiledMethod or Compiler such as

encodeTempNames: isInteractive
    ^interactive or: [SourceFiles isNil]
 
2009/12/22  <[hidden email]>:
> Andreas Raab uploaded a new version of Compiler to project The Trunk:
> http://source.squeak.org/trunk/Compiler-ar.108.mcz
>
> ==================== Summary ====================
>
> Name: Compiler-ar.108
> Author: ar
> Time: 22 December 2009, 12:48:23 pm
> UUID: 538bb76e-8967-e445-9b2c-161c98c289d6
> Ancestors: Compiler-ar.107
>
> CompiledMethodTrailer phase 2.
>
> =============== Diff against Compiler-ar.107 ===============
>
> Item was changed:
>  ----- Method: Compiler>>compiledMethodFor:in:to:notifying:ifFail:logged: (in category 'public access') -----
>  compiledMethodFor: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>        "Compiles the sourceStream into a parse tree, then generates code
>         into a method, and answers it.  If receiver is not nil, then the text can
>         refer to instance variables of that receiver (the Inspector uses this).
>         If aContext is not nil, the text can refer to temporaries in that context
>         (the Debugger uses this). If aRequestor is not nil, then it will receive a
>         notify:at: message before the attempt to evaluate is aborted."
>
>        | methodNode method |
>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>        methodNode := self translate: sourceStream noPattern: true ifFail: [^failBlock value].
> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
> +               ifFalse: [methodNode generate].
> +
> -       method := methodNode generate: #(0 0 0 0).
> -       self interactive ifTrue:
> -               [method := method copyWithTempsFromMethodNode: methodNode].
>        logFlag ifTrue:
>                [SystemChangeNotifier uniqueInstance evaluated: sourceStream contents context: aContext].
>        ^method!
>
> Item was changed:
>  ----- Method: Compiler>>evaluate:in:to:notifying:ifFail:logged: (in category 'public access') -----
>  evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag
>        "Compiles the sourceStream into a parse tree, then generates code into a
>        method. This method is then installed in the receiver's class so that it
>        can be invoked. In other words, if receiver is not nil, then the text can
>        refer to instance variables of that receiver (the Inspector uses this). If
>        aContext is not nil, the text can refer to temporaries in that context (the
>        Debugger uses this). If aRequestor is not nil, then it will receive a
>        notify:at: message before the attempt to evaluate is aborted. Finally, the
>        compiled method is invoked from here as DoIt or (in the case of
>        evaluation in aContext) DoItIn:. The method is subsequently removed
>        from the class, but this will not get done if the invocation causes an
>        error which is terminated. Such garbage can be removed by executing:
>        Smalltalk allBehaviorsDo: [:cl | cl removeSelector: #DoIt; removeSelector:
>        #DoItIn:]."
>
>        | methodNode method value toLog itsSelection itsSelectionString |
>        class := (aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class.
>        self from: textOrStream class: class context: aContext notifying: aRequestor.
>        methodNode := self translate: sourceStream noPattern: true ifFail:
>                [^failBlock value].
> +
> +       method := self interactive ifTrue: [    methodNode generateWithTempNames ]
> +               ifFalse: [methodNode generate].
> -       method := methodNode generate: #(0 0 0 0).
> -       self interactive ifTrue:
> -               [method := method copyWithTempsFromMethodNode: methodNode].
>
>        value := receiver
>                                withArgs: (context ifNil: [#()] ifNotNil: [{context}])
>                                executeMethod: method.
>
>        logFlag ifTrue:[
>                toLog := ((requestor respondsTo: #selection)
>                        and:[(itsSelection := requestor selection) notNil
>                        and:[(itsSelectionString := itsSelection asString) isEmptyOrNil not]])
>                                ifTrue:[itsSelectionString]
>                                ifFalse:[sourceStream contents].
>                SystemChangeNotifier uniqueInstance evaluated: toLog context: aContext].
>        ^ value!
>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Igor Stasenko
2009/12/22 Eliot Miranda <[hidden email]>:

>
>
> On Tue, Dec 22, 2009 at 5:41 AM, Nicolas Cellier
> <[hidden email]> wrote:
>>
>> Why does this depend on interactive ?
>>
>>       method := self interactive ifTrue: [    methodNode
>> generateWithTempNames ]
>>               ifFalse: [methodNode generate].
>>
>> Nicolas
>>
>
>
> The assumption is that one wants temp names preserved in doits, but is not
> particularly interested in temp names in automatic compiles.  Essentially
> the system is in two modes.  One, with source, does not preserve temp names
> except for doits because the temp names are in the sources files.  The
> other, without sources, converts all methods to sourceless with encoded temp
> names.  But this isn't yet reflected in the code.  The code would better
> read something like
>       method := (self interactive or: [self noSourcesFiles])
>                       ifTrue: [methodNode generateWithTempNames]
>                       ifFalse: [methodNode generate]
> and of course (self interactive or: [self noSourcesFiles]) could be
> extracted into e.g. a class-side method on CompiledMethod or Compiler such
> as
> encodeTempNames: isInteractive
>     ^interactive or: [SourceFiles isNil]
>

ideally, the decision what to do should be delegated to aRequestor, so
code may be something like:

method := methodNode generate: (aRequestor methodTrailerFor: methodNode)

Meanwhile i made own version of Compiler>>evaluate: textOrStream in:
aContext to: receiver notifying: aRequestor ifFail: failBlock logged:
logFlag

which saving a full source code of doit in trailer, if its interactive.

so evaluating given code:
--------------
" doing this"

thisContext method getSource
--------------

prints:

 'DoIt
" doing this"

thisContext method getSource
 '

if you find this useful, i could push change to trunk.


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Compiler-ar.108.mcz

Eliot Miranda-2


On Tue, Dec 22, 2009 at 1:12 PM, Igor Stasenko <[hidden email]> wrote:
2009/12/22 Eliot Miranda <[hidden email]>:
>
>
> On Tue, Dec 22, 2009 at 5:41 AM, Nicolas Cellier
> <[hidden email]> wrote:
>>
>> Why does this depend on interactive ?
>>
>>       method := self interactive ifTrue: [    methodNode
>> generateWithTempNames ]
>>               ifFalse: [methodNode generate].
>>
>> Nicolas
>>
>
>
> The assumption is that one wants temp names preserved in doits, but is not
> particularly interested in temp names in automatic compiles.  Essentially
> the system is in two modes.  One, with source, does not preserve temp names
> except for doits because the temp names are in the sources files.  The
> other, without sources, converts all methods to sourceless with encoded temp
> names.  But this isn't yet reflected in the code.  The code would better
> read something like
>       method := (self interactive or: [self noSourcesFiles])
>                       ifTrue: [methodNode generateWithTempNames]
>                       ifFalse: [methodNode generate]
> and of course (self interactive or: [self noSourcesFiles]) could be
> extracted into e.g. a class-side method on CompiledMethod or Compiler such
> as
> encodeTempNames: isInteractive
>     ^interactive or: [SourceFiles isNil]
>

ideally, the decision what to do should be delegated to aRequestor, so
code may be something like:

method := methodNode generate: (aRequestor methodTrailerFor: methodNode)

Except that aRequestor could be nil..  In fact I could also imagine that a sourceless system wouldn't necessarily want to encode temp names (for space and speed) in a sealed application.  So the choices are

if interactive always encode with sources
if not interactive
     if sources do not encode (temps in source)
     if not sources defer to a preference

And set the preference to true when doing abandonSources.
 

Meanwhile i made own version of Compiler>>evaluate: textOrStream in:
aContext to: receiver notifying: aRequestor ifFail: failBlock logged:
logFlag

which saving a full source code of doit in trailer, if its interactive.

so evaluating given code:
--------------
" doing this"

thisContext method getSource
--------------

prints:

 'DoIt
" doing this"

thisContext method getSource
 '

if you find this useful, i could push change to trunk.

I don't know.  Keeping temp names is adequate when doing doits for me.  If a doit gets big enough to need a comment it probably needs to be a proper method ;)  But what do others think?



--
Best regards,
Igor Stasenko AKA sig.