Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.200.mcz
==================== Summary ====================
Name: Compiler-nice.200
Author: nice
Time: 30 March 2011, 10:47:39.106 pm
UUID: e97c15bd-d6b0-b648-9bde-fb0e2ffde315
Ancestors: Compiler-nice.199
minor ifNil refactoring
=============== Diff against Compiler-nice.199 ===============
Item was changed:
----- Method: BlockLocalTempCounter>>tempCountForBlockAt:in: (in category 'initialize-release') -----
tempCountForBlockAt: pc in: method
"Compute the number of local temporaries in a block.
If the block begins with a sequence of push: nil bytecodes then some of
These could be initializing local temps. We can only reliably disambuguate
them from other uses of nil by parsing the stack and seeing what the offset
of the stack pointer is at the end of the block.
There are short-cuts. The ones we take here are
- if there is no sequence of push nils there can be no local temps
- we follow forward jumps to shorten the amount of scanning"
stackPointer := 0.
scanner := InstructionStream new method: method pc: pc.
scanner interpretNextInstructionFor: self.
+ blockEnd ifNil:
- blockEnd isNil ifTrue:
[self error: 'pc is not that of a block'].
scanner nextByte = Encoder pushNilCode ifTrue:
[joinOffsets := Dictionary new.
[scanner pc < blockEnd] whileTrue:
[scanner interpretNextInstructionFor: self]].
^stackPointer!
Item was changed:
----- Method: BlockLocalTempCounter>>testTempCountForBlockAt:in: (in category 'initialize-release') -----
testTempCountForBlockAt: startPc in: method
"Compute the number of local temporaries in a block.
If the block begins with a sequence of push: nil bytecodes then some of
These could be initializing local temps. We can only reliably disambuguate
them from other uses of nil by parsing the stack and seeing what the offset
of the stack pointer is at the end of the block.There are short-cuts. The only
one we take here is
- if there is no sequence of push nils there can be no local temps"
| symbolicLines line prior thePc |
symbolicLines := Dictionary new.
method symbolicLinesDo:
[:pc :lineForPC| symbolicLines at: pc put: lineForPC].
stackPointer := 0.
scanner := InstructionStream new method: method pc: startPc.
scanner interpretNextInstructionFor: self.
+ blockEnd ifNil:
- blockEnd isNil ifTrue:
[self error: 'pc is not that of a block'].
scanner nextByte = Encoder pushNilCode ifTrue:
[joinOffsets := Dictionary new.
[scanner pc < blockEnd] whileTrue:
[line := symbolicLines at: scanner pc.
prior := stackPointer.
thePc := scanner pc.
scanner interpretNextInstructionFor: self.
Transcript cr; print: prior; nextPutAll: '->'; print: stackPointer; tab; print: thePc; tab; nextPutAll: line; flush]].
^stackPointer!
Item was changed:
----- Method: Parser>>encoder (in category 'public access') -----
encoder
+ ^encoder ifNil:
+ [encoder := EncoderForV3PlusClosures new]!
- encoder isNil ifTrue:
- [encoder := EncoderForV3PlusClosures new].
- ^encoder!
Item was changed:
----- Method: Parser>>encoderClass: (in category 'public access') -----
encoderClass: anEncoderClass
+ encoder ifNotNil: [
+ self error: 'encoder already set'].
- encoder notNil ifTrue:
- [self error: 'encoder already set'].
encoder := anEncoderClass new!
Item was changed:
----- Method: RemoteTempVectorNode>>printDefinitionForClosureAnalysisOn: (in category 'printing') -----
printDefinitionForClosureAnalysisOn: aStream
| refs |
aStream
nextPut: ${;
nextPutAll: key.
definingScope ifNotNil: [definingScope blockExtent ifNotNil: [:be| aStream nextPutAll: ' d@'; print: be first]].
+ readingScopes ifNotNil: [
+ refs := Set new.
- readingScopes notNil ifTrue:
- [refs := Set new.
readingScopes do: [:elems| refs addAll: elems].
refs asSortedCollection do: [:read| aStream nextPutAll: ' r@'; print: read]].
remoteTemps
do: [:rt| rt printDefinitionForClosureAnalysisOn: aStream]
separatedBy: [aStream nextPut: $,; space].
aStream nextPut: $}!
Item was changed:
----- Method: TempVariableNode>>sizeCodeForLoad: (in category 'code generation') -----
sizeCodeForLoad: encoder
+ ^remoteNode
+ ifNil: [0]
+ ifNotNil: [remoteNode sizeCodeForLoadFor: self encoder: encoder]!
- ^remoteNode isNil
- ifTrue: [0]
- ifFalse: [remoteNode sizeCodeForLoadFor: self encoder: encoder]!
Nicolas Cellier uploaded a new version of CollectionsTests to project The Trunk:
http://source.squeak.org/trunk/CollectionsTests-nice.184.mcz
==================== Summary ====================
Name: CollectionsTests-nice.184
Author: nice
Time: 30 March 2011, 9:57:18.627 pm
UUID: 88386be6-a998-42c7-87c4-efd261e64f02
Ancestors: CollectionsTests-nice.183
Use #newCompiler #newParser
=============== Diff against CollectionsTests-nice.183 ===============
Item was changed:
----- Method: CharacterTest>>testPrintStringAll (in category 'testing-printing') -----
testPrintStringAll
Character allCharacters do: [ :each |
+ self assert: (self class newCompiler
- self assert: (self class compilerClass
evaluate: each printString) = each ].!
Item was changed:
----- Method: CharacterTest>>testStoreStringAll (in category 'testing-printing') -----
testStoreStringAll
Character allCharacters do: [ :each |
+ self assert: (self class newCompiler
- self assert: (self class compilerClass
evaluate: each storeString) = each ].!
Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.199.mcz
==================== Summary ====================
Name: Compiler-nice.199
Author: nice
Time: 30 March 2011, 9:56:40.201 pm
UUID: 40f46685-08e8-4661-95bd-8be4327c963b
Ancestors: Compiler-IgorStasenko.198
Use #newCompiler #newParser
Move some #evaluate: methods to instance side to enable (self class newCompiler evaluate: 'nil') usage
=============== Diff against Compiler-IgorStasenko.198 ===============
Item was changed:
----- Method: Compiler class>>new (in category 'accessing') -----
new
+ ^ super new parser: self newParser!
- ^ super new parser: self parserClass new!
Item was added:
+ ----- Method: Compiler>>evaluate: (in category 'public access') -----
+ evaluate: textOrString
+ "See evaluate:for:notifying:logged:. If a compilation error occurs,
+ a Syntax Error view is created rather than notifying any requestor.
+ Compilation is carried out with respect to nil, i.e., no object, and the
+ invocation is not logged."
+
+ ^self evaluate: textOrString for: nil logged: false!
Item was added:
+ ----- Method: Compiler>>evaluate:for:logged: (in category 'public access') -----
+ evaluate: textOrString for: anObject logged: logFlag
+ "See evaluate:for:notifying:logged:. If a compilation error occurs,
+ a Syntax Error view is created rather than notifying any requestor."
+
+ ^self evaluate: textOrString for: anObject notifying: nil logged: logFlag!
Item was added:
+ ----- Method: Compiler>>evaluate:for:notifying:logged: (in category 'public access') -----
+ evaluate: textOrString for: anObject notifying: aController logged: logFlag
+ "Compile and execute the argument, textOrString with respect to the class
+ of anObject. If a compilation error occurs, notify aController. If both
+ compilation and execution are successful then, if logFlag is true, log
+ (write) the text onto a system changes file so that it can be replayed if
+ necessary."
+
+ ^ self
+ evaluate: textOrString
+ in: nil
+ to: anObject
+ notifying: aController
+ ifFail: [^nil]
+ logged: logFlag.!
Item was changed:
----- Method: Compiler>>evaluate:in:to: (in category 'public access') -----
evaluate: aString in: aContext to: aReceiver
"evaluate aString in the given context, and return the result. 2/2/96 sw"
+ ^self
+ evaluate: aString
+ in: aContext
+ to: aReceiver
+ notifying: nil
+ ifFail: [^ #failedDoit]!
- | result |
- result := self
- evaluate: aString
- in: aContext
- to: aReceiver
- notifying: nil
- ifFail: [^ #failedDoit].
- ^ result!
Item was added:
+ ----- Method: Compiler>>evaluate:logged: (in category 'public access') -----
+ evaluate: textOrString logged: logFlag
+ "See evaluate:for:notifying:logged:. If a compilation error occurs,
+ a Syntax Error view is created rather than notifying any requestor.
+ Compilation is carried out with respect to nil, i.e., no object."
+
+ ^self evaluate: textOrString for: nil logged: logFlag!
Item was added:
+ ----- Method: Compiler>>evaluate:notifying:logged: (in category 'public access') -----
+ evaluate: textOrString notifying: aController logged: logFlag
+ "See evaluate:for:notifying:logged:. Compilation is carried out
+ with respect to nil, i.e., no object."
+
+ ^self evaluate: textOrString for: nil notifying: aController logged: logFlag!
Item was changed:
----- Method: Compiler>>parser (in category 'public access') -----
parser
+ parser ifNil: [parser := (class ifNil: [self class]) newParser].
- parser ifNil: [parser := self parserClass new].
^parser!
Item was removed:
- ----- Method: Compiler>>parserClass (in category 'public access') -----
- parserClass
-
- ^parser ifNil: [self class parserClass] ifNotNil: [parser class]!
Item was changed:
----- Method: MethodNode>>blockExtentsToTempsMap (in category 'debugger support') -----
blockExtentsToTempsMap
"Answer a Dictionary of blockExtent to temp locations for the current method.
This is used by the debugger to locate temp vars in contexts. A temp map
entry is a pair of the temp's name and its index, where an index is either an
integer for a normal temp or a pair of the index of the indirect temp vector
containing the temp and the index of the temp in its indirect temp vector."
^encoder blockExtentsToTempsMap ifNil:
[| methNode |
+ methNode := encoder classEncoding newParser
- methNode := encoder classEncoding parserClass new
encoderClass: encoder class;
parse: (sourceText ifNil: [self decompileString])
class: self methodClass.
"As a side effect generate: creates data needed for the map."
methNode generate.
methNode encoder blockExtentsToTempsMap]!
Item was changed:
----- Method: MethodNode>>rawSourceRangesAndMethodDo: (in category 'source mapping') -----
rawSourceRangesAndMethodDo: aBinaryBlock
"Evaluate aBinaryBlock with the rawSourceRanges and method generated from the receiver."
| methNode method |
+ methNode := encoder classEncoding newParser
- methNode := encoder classEncoding parserClass new
encoderClass: encoder class;
parse: (sourceText "If no source, use decompile string as source to map from"
ifNil: [self decompileString]
ifNotNil: [sourceText])
class: self methodClass.
method := methNode generate. "set bytecodes to map to"
^aBinaryBlock
value: methNode encoder rawSourceRanges
value: method!
Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.435.mcz
==================== Summary ====================
Name: Collections-nice.435
Author: nice
Time: 30 March 2011, 9:50:07.129 pm
UUID: f53b9d14-89c3-4105-8e0b-41cd10076918
Ancestors: Collections-nice.434
Use #newCompiler #newParser
=============== Diff against Collections-nice.434 ===============
Item was changed:
----- Method: Text>>makeSelectorBold (in category 'emphasis') -----
makeSelectorBold
"For formatting Smalltalk source code, set the emphasis of that portion of
the receiver's string that parses as a message selector to be bold."
| parser i |
string size = 0 ifTrue: [^ self].
i := 0.
[(string at: (i := i + 1)) isSeparator] whileTrue.
(string at: i) = $[ ifTrue: [^ self]. "block, no selector"
+ [(parser := Compiler newParser) parseSelector: string] on: Error do: [^ self].
- [(parser := Compiler parserClass new) parseSelector: string] on: Error do: [^ self].
self makeBoldFrom: 1 to: (parser endOfLastToken min: string size)!
Item was changed:
----- Method: Text>>makeSelectorBoldIn: (in category 'emphasis') -----
makeSelectorBoldIn: aClass
"For formatting Smalltalk source code, set the emphasis of that portion of
the receiver's string that parses as a message selector to be bold."
| parser |
string size = 0 ifTrue: [^self].
+ (parser := aClass newParser) parseSelector: string.
- (parser := aClass parserClass new) parseSelector: string.
self makeBoldFrom: 1 to: (parser endOfLastToken min: string size)!
Nicolas Cellier uploaded a new version of Traits to project The Trunk:
http://source.squeak.org/trunk/Traits-nice.288.mcz
==================== Summary ====================
Name: Traits-nice.288
Author: nice
Time: 30 March 2011, 9:47:27.896 pm
UUID: 2c2016d2-acf3-448a-b3b9-836089b17a9e
Ancestors: Traits-nice.287
Use #newCompiler #newParser
=============== Diff against Traits-nice.287 ===============
Item was changed:
----- Method: ClassDescription>>replaceSelector:withAlias:in: (in category '*Traits-NanoKernel') -----
replaceSelector: originalSelector withAlias: aliasSelector in: source
"replaces originalSelector with aliasSelector in in given source code"
| oldKeywords newKeywords args selectorWithArgs s |
oldKeywords := originalSelector keywords.
newKeywords := aliasSelector keywords.
oldKeywords size = newKeywords size ifFalse:[self error: 'Keyword mismatch'].
+ args := (self newParser parseArgsAndTemps: source asString notifying: nil)
- args := (self parserClass new parseArgsAndTemps: source asString notifying: nil)
copyFrom: 1 to: originalSelector numArgs.
selectorWithArgs := String streamContents: [:stream |
newKeywords keysAndValuesDo: [:index :keyword |
stream nextPutAll: keyword.
stream space.
args size >= index ifTrue: [
stream nextPutAll: (args at: index); space]]].
s := source asString readStream.
oldKeywords do: [ :each | s match: each ].
args isEmpty ifFalse: [ s match: args last ].
^selectorWithArgs withBlanksTrimmed asText , s upToEnd
!
Item was changed:
----- Method: ClassDescription>>traitAddSelector:withMethod: (in category '*Traits-NanoKernel') -----
traitAddSelector: selector withMethod: traitMethod
"Add a method inherited from a trait.
Recompiles to avoid sharing and implement aliasing."
| oldMethod source methodNode newMethod originalSelector |
oldMethod := self compiledMethodAt: selector ifAbsent:[nil].
oldMethod ifNotNil:[
"The following is an important optimization as it prevents exponential
growth in recompilation. If T1 is used by T2 and T2 by T3 then (without
this optimization) any change in T1 would cause all methods in T2 to be
recompiled and each recompilation of a method in T2 would cause T3
to be fully recompiled. The test eliminates all such situations."
(oldMethod sameTraitCodeAs: traitMethod) ifTrue:[^oldMethod].
].
originalSelector := traitMethod selector.
source := traitMethod methodClass sourceCodeAt: originalSelector.
originalSelector == selector ifFalse:[
"Replace source selectors for aliases"
source := self replaceSelector: originalSelector withAlias: selector in: source.
].
+ methodNode := self newCompiler
- methodNode := self compilerClass new
compile: source in: self classified: nil notifying: nil ifFail:[^nil].
newMethod := methodNode generate: self defaultMethodTrailer.
newMethod putSource: source fromParseNode: methodNode inFile: 2
withPreamble: [:f | f cr; nextPut: $!!; nextChunkPut: 'Trait method'; cr].
newMethod originalTraitMethod: traitMethod.
^super addSelectorSilently: selector withMethod: newMethod.!