[squeak-dev] The Trunk: Compiler-jcg.106.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Dec 18 08:13:01 UTC 2009


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!




More information about the Squeak-dev mailing list