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! |
Free forum by Nabble | Edit this page |