The Trunk: Compiler-jcg.106.mcz

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

The Trunk: Compiler-jcg.106.mcz

commits-2
Joshua Gargus uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-jcg.106.mcz

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

Name: Compiler-jcg.106
Author: jcg
Time: 18 December 2009, 12:12:50 pm
UUID: a95c76dc-5670-3c45-af7e-75c89f852c95
Ancestors: Compiler-ul.105

Inline the transformation defined by FutureMaker in Kernel-jcg.329.

=============== Diff against Compiler-ul.105 ===============

Item was added:
+ ----- Method: FutureNode>>emitForValue:on: (in category 'code generation') -----
+ emitForValue: stack on: strm
+ ^valueNode emitForValue: stack on: strm!

Item was added:
+ ----- Method: FutureNode>>futureMessage:arguments:from:sourceRange: (in category 'initialize-release') -----
+ futureMessage: selName arguments: args  from: encoder sourceRange: range
+ futureSelector := selName.
+ futureArgs := args.
+ ^self!

Item was added:
+ ----- Method: FutureNode>>sizeCodeForBlockValue: (in category 'code generation (new scheme)') -----
+ sizeCodeForBlockValue: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ (futureArgs isNil or: [futureSelector isNil]) ifTrue:
+ [^self error: 'Futures must be sent messages'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ effectNode := MessageNode new
+ receiver: receiver
+ selector: #futureDo:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^effectNode sizeCodeForValue: encoder!

Item was added:
+ ----- Method: FutureNode>>sizeForEffect: (in category 'code generation') -----
+ sizeForEffect: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ effectNode := MessageNode new
+ receiver: receiver
+ selector: #futureDo:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^effectNode sizeForEffect: encoder!

Item was added:
+ ----- Method: FutureNode>>accept: (in category 'visiting') -----
+ accept: aVisitor
+ ^aVisitor visitFutureNode: self!

Item was added:
+ ----- Method: FutureNode>>isFutureNode (in category 'testing') -----
+ isFutureNode
+ ^true!

Item was added:
+ ----- Method: FutureNode>>receiver (in category 'accessing') -----
+ receiver
+ ^receiver!

Item was added:
+ ParseNode subclass: #FutureNode
+ instanceVariableNames: 'receiver originalSelector futureSelector futureDelta futureArgs effectNode valueNode'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Compiler-ParseNodes'!
+
+ !FutureNode commentStamp: 'jcg 12/17/2009 02:03' prior: 0!
+ Compile-time transformation of #future and #future: messages.  Use is best described through examples:
+
+ receiver future doSomething: arg1 withArgs: arg2.
+ (receiver future: 2000) doSomethingElse
+
+ The first means to immediately schedule #doSomething:withArgs: for asyncronous evaluation.  The second means to wait 2000 milliseconds before scheduling #doSomethingElse for asynchronous evaluation.
+
+ These are transformed into either #futureDo:at:args: or #futureSend:at:args:, depending on whether the result is used.  Let's look at a few examples.
+
+ [receiver future foo. 2+2] value.
+ true ifTrue: [^receiver future foo].
+ arraySize := receiver future getArray wait size.
+
+ In the first case, the result is never used, so the message #futureDo:at:args: is generated.  In the second case, the result is answered from the current method.  Since we don't do any cross-method analysis, we have to assume that the result is needed for a later computation.  The result is provided in the form of a Promise, which will resolve to a value when the asynchronous evaluation has completed.  Creating and resolving this Promise is the responsibility of #futureSend:at:args:, which is generated instead of #futureDo:at:args: when code-analysis indicates that the result of the message might be used.  The third example is another one where #futureSend:at:args: is generated.
+
+ See the default implementations of #futureDo:at:args: and #futureSend:at:args: in Object.  Subclasses are free to override the default implementations to achieve specific effects.  For example, this functionality originated in the Croquet class TFarRef.  If you have a TFarRef to a replicated object, then sending 'aTFarRef future foo' results in a message being sent over the network to each replica of the object referenced by aTFarRef.  We might also use far-refs, for example, to send a message to an object in another Hydra object-memory.!

Item was added:
+ ----- Method: FutureNode>>sizeForValue: (in category 'code generation') -----
+ sizeForValue: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ valueNode := MessageNode new
+ receiver: receiver
+ selector: #futureSend:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^valueNode sizeForValue: encoder!

Item was added:
+ ----- Method: FutureNode>>emitCodeForEffect:encoder: (in category 'code generation (new scheme)') -----
+ emitCodeForEffect: stack encoder: encoder
+ ^effectNode emitCodeForEffect: stack encoder: encoder!

Item was added:
+ ----- Method: FutureNode>>sizeForBlockValue: (in category 'code generation') -----
+ sizeForBlockValue: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ effectNode := MessageNode new
+ receiver: receiver
+ selector: #futureDo:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^effectNode sizeForValue: encoder!

Item was added:
+ ----- Method: FutureNode>>sizeCodeForValue: (in category 'code generation (new scheme)') -----
+ sizeCodeForValue: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ (futureArgs isNil or: [futureSelector isNil]) ifTrue:
+ [^self error: 'Futures must be sent messages'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ valueNode := MessageNode new
+ receiver: receiver
+ selector: #futureSend:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^valueNode sizeCodeForValue: encoder!

Item was added:
+ ----- Method: FutureNode>>emitForEffect:on: (in category 'code generation') -----
+ emitForEffect: stack on: strm
+ ^effectNode emitForEffect: stack on: strm!

Item was added:
+ ----- Method: FutureNode>>sizeCodeForEffect: (in category 'code generation (new scheme)') -----
+ sizeCodeForEffect: encoder
+ receiver == NodeSuper ifTrue: [^self error: 'Futures cannot send to future'].
+ (futureArgs isNil or: [futureSelector isNil]) ifTrue:
+ [^self error: 'Futures must be sent messages'].
+ encoder sharableLitIndex: originalSelector. "to find its senders"
+ futureDelta ifNil:[futureDelta := encoder encodeLiteral: 0].
+ effectNode := MessageNode new
+ receiver: receiver
+ selector: #futureDo:at:args:
+ arguments: (Array
+ with: (encoder encodeLiteral: futureSelector)
+ with: futureDelta
+ with: (BraceNode new elements: futureArgs))
+ precedence: 3
+ from: encoder.
+ ^effectNode sizeCodeForEffect: encoder!

Item was added:
+ ----- Method: FutureNode>>emitCodeForValue:encoder: (in category 'code generation (new scheme)') -----
+ emitCodeForValue: stack encoder: encoder
+ ^valueNode emitCodeForValue: stack encoder: encoder!

Item was added:
+ ----- Method: FutureNode>>originalSelector (in category 'accessing') -----
+ originalSelector
+ ^originalSelector!

Item was added:
+ ----- Method: FutureNode>>emitCodeForBlockValue:encoder: (in category 'code generation (new scheme)') -----
+ emitCodeForBlockValue: stack encoder: encoder
+ "Generate code for evaluating the last statement in a block."
+ ^effectNode emitCodeForValue: stack encoder: encoder!

Item was added:
+ ----- Method: FutureNode>>futureSelector (in category 'accessing') -----
+ futureSelector
+ ^futureSelector!

Item was added:
+ ----- Method: FutureNode>>receiver:selector:arguments:precedence:from:sourceRange: (in category 'initialize-release') -----
+ receiver: rcvr selector: selector arguments: args precedence: p from: encoder sourceRange: range
+ receiver := rcvr.
+ originalSelector := selector.
+ originalSelector == #future: ifTrue:[futureDelta := args first].
+ encoder noteSourceRange: range forNode: self.!

Item was added:
+ ----- Method: FutureNode>>analyseTempsWithin:rootNode:assignmentPools: (in category 'code generation (closures)') -----
+ analyseTempsWithin: scopeBlock "<BlockNode>" rootNode: rootNode "<MethodNode>" assignmentPools: assignmentPools "<Dictionary>"
+ { receiver. futureDelta }, (futureArgs ifNil: [#()]) do:
+ [:node|
+ node == nil ifFalse:
+ [node analyseTempsWithin: scopeBlock rootNode: rootNode assignmentPools: assignmentPools]]!

Item was added:
+ ----- Method: FutureNode>>emitForBlockValue:on: (in category 'code generation') -----
+ emitForBlockValue: stack on: strm
+ "Generate code for evaluating the last statement in a block."
+ ^effectNode emitForValue: stack on: strm!