[squeak-dev] The Trunk: Compiler-eem.154.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Aug 12 21:05:07 UTC 2010


Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.154.mcz

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

Name: Compiler-eem.154
Author: eem
Time: 12 August 2010, 2:04:48.383 pm
UUID: 38a702f7-88c0-4176-9213-ce25c77bd3ef
Ancestors: Compiler-nice.153

Fix decompilation of blocks with indirect temps, e.g.
	| x y |
	[:a :b | x := a. y := b. x+y] decompile
Correct comment of evaluate:in:to:notifying:ifFail:logged: not
we no longer install doits in dictionaries but use withArgs:executeMethod:

=============== Diff against Compiler-nice.153 ===============

Item was changed:
  ----- Method: Decompiler>>pushClosureCopyNumCopiedValues:numArgs:blockSize: (in category 'instruction decoding') -----
  pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize
  	| copiedValues |
  	self sawClosureBytecode.
+ 	copiedValues := ((1 to: numCopied) collect: [:ign| stack removeLast]) reversed.
- 	numCopied > 0
- 		ifTrue:
- 			[copiedValues := Array new: numCopied.
- 			 numLocalTemps == #decompileBlock: ifTrue: "Hack fake temps for copied values"
- 				[1 to: numCopied do: [:i| stack addLast: (constructor codeTemp: i - 1)]].
- 			 numCopied to: 1 by: -1 do:
- 				[:i|
- 				copiedValues at: i put: stack removeLast]]
- 		ifFalse:
- 			[copiedValues := #()].
  	self doClosureCopyCopiedValues: copiedValues numArgs: numArgs blockSize: blockSize!

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. 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 via withArgs:executeMethod:, hence
+ 	 the system no longer creates Doit method litter on errors."
- 	"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].
- 	methodNode := self translate: sourceStream noPattern: true ifFail:
- 		[^failBlock value].
  
+ 	method := self interactive
+ 				ifTrue: [methodNode generateWithTempNames]
+ 				ifFalse: [methodNode generate].
+ 
- 	method := self interactive ifTrue: [ 	methodNode generateWithTempNames ] 
- 		ifFalse: [methodNode generate].
- 	
  	value := receiver
  				withArgs: (context ifNil: [#()] ifNotNil: [{context}])
  				executeMethod: method.
  
+ 	logFlag ifTrue:
+ 		[toLog := ((requestor respondsTo: #selection)  
- 	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!

Item was changed:
  ----- Method: Decompiler>>decompileBlock: (in category 'public access') -----
  decompileBlock: aBlock 
  	"Decompile aBlock, returning the result as a BlockNode.  
  	Show temp names from source if available."
  	"Decompiler new decompileBlock: [3 + 4]"
+ 	| startpc end homeClass blockNode methodNode home |
- 	| startpc end homeClass blockNode methodNode home source |
  	(home := aBlock home) ifNil: [^ nil].
  	method := home method.
  	(homeClass := home methodClass) == #unknown ifTrue: [^ nil].
+ 	aBlock isClosure ifTrue:
+ 		[(methodNode := method decompileWithTemps)
+ 			ifNil: [^nil]
+ 			ifNotNil: [methodNode nodesDo: [:node| node pc = aBlock startpc ifTrue: [^node]]].
+ 		 ^self error: 'cannot find block node matching aBlock'].
  	constructor := self constructorForMethod: aBlock method.
+ 	
+ 	self withTempNames: method methodNode tempNames.
+ 
- 	self withTempNames: (method tempNamesString ifNil:[
- 	method fileIndex ~~ 0 ifTrue: "got any source code?"
- 		[source := [method getSourceFromFile]
- 						on: Error
- 						do: [:ex | ^ nil].
- 		 methodNode := [homeClass compilerClass new
- 								parse: source
- 								in: homeClass
- 								notifying: nil]
- 							on: SyntaxErrorNotification
- 							do: [:ex | ^ nil].
- 		methodNode schematicTempNamesString]]).
  	self initSymbols: homeClass.
  	startpc := aBlock startpc.
+ 	end := aBlock endPC.
- 	end := aBlock isClosure
- 				ifTrue: [(method at: startpc - 2) * 256
- 					  + (method at: startpc - 1) + startpc - 1]
- 				ifFalse:
- 					[(method at: startpc - 2) \\ 16 - 4 * 256
- 					+ (method at: startpc - 1) + startpc - 1].
  	stack := OrderedCollection new: method frameSize.
  	caseExits := OrderedCollection new.
  	statements := OrderedCollection new: 20.
+ 	super method: method pc: startpc - 5.
- 	super
- 		method: method
- 		pc: (aBlock isClosure ifTrue: [startpc - 4] ifFalse: [startpc - 5]).
- 	aBlock isClosure ifTrue:
- 		[numLocalTemps := #decompileBlock: "Get pushClosureCopy... to hack fake temps for copied values"].
  	blockNode := self blockTo: end.
  	stack isEmpty ifFalse: [self error: 'stack not empty'].
  	^blockNode statements first!

Item was changed:
  ----- Method: Decompiler>>doClosureCopyCopiedValues:numArgs:blockSize: (in category 'control') -----
  doClosureCopyCopiedValues: blockCopiedValues numArgs: numArgs blockSize: blockSize
+ 	| startpc savedTemps savedTempVarCount savedNumLocalTemps
- 	| savedTemps savedTempVarCount savedNumLocalTemps
  	  jump blockArgs blockTemps blockTempsOffset block |
  	savedTemps := tempVars.
  	savedTempVarCount := tempVarCount.
  	savedNumLocalTemps := numLocalTemps.
+ 	jump := blockSize + (startpc := pc).
- 	jump := blockSize + pc.
  	numLocalTemps := BlockLocalTempCounter tempCountForBlockAt: pc - 4 in: method.
  	blockTempsOffset := numArgs + blockCopiedValues size.
  	(blockStartsToTempVars notNil "implies we were intialized with temp names."
  	 and: [blockStartsToTempVars includesKey: pc])
  		ifTrue:
  			[tempVars := blockStartsToTempVars at: pc]
  		ifFalse:
  			[blockArgs := (1 to: numArgs) collect:
  							[:i| (constructor
  									codeTemp: i - 1
  									named: 't', (tempVarCount + i) printString)
  								  beBlockArg].
  			blockTemps := (1 to: numLocalTemps) collect:
  							[:i| constructor
  									codeTemp: i + blockTempsOffset - 1
  									named: 't', (tempVarCount + i + numArgs) printString].
  			tempVars := blockArgs, blockCopiedValues, blockTemps].
  	numLocalTemps timesRepeat:
  		[self interpretNextInstructionFor: self.
  		 stack removeLast].
  	tempVarCount := tempVarCount + numArgs + numLocalTemps.
  	block := self blockTo: jump.
+ 	stack addLast: ((constructor
+ 						codeArguments: (tempVars copyFrom: 1 to: numArgs)
+ 						temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps)
+ 						block: block)
+ 							pc: startpc;
+ 							yourself).
- 	stack addLast: (constructor
- 					codeArguments: (tempVars copyFrom: 1 to: numArgs)
- 					temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps)
- 					block: block).
  	tempVars := savedTemps.
  	tempVarCount := savedTempVarCount.
  	numLocalTemps := savedNumLocalTemps!




More information about the Squeak-dev mailing list