'From Cuis 2.3 of 22 March 2010 [latest update: #472] on 7 April 2010 at 9:45:59 pm'!

!CodeHolder methodsFor: 'message list' stamp: 'jmv 4/7/2010 20:02'!
selectedMessage
	"Answer a copy of the source code for the selected message.  This generic version is probably actually never reached, since every subclass probably reimplements and does not send to super.  In time, ideally, most, or all, reimplementors would vanish and all would defer instead to a universal version right here.  Everything in good time."

	| class selector method |
	contents ifNotNil: [^ contents copy].

	self showingDecompile ifTrue:
		[^ self decompiledSourceIntoContentsWithTempNames: false ].

	class _ self selectedClassOrMetaClass.
	(class isNil or: [(selector _ self selectedMessageName) isNil]) ifTrue: [^ ''].
	method _ class compiledMethodAt: selector ifAbsent: [^ ''].	"method deleted while in another project"
	currentCompiledMethod _ method.

	^ contents _ (self showComment
		ifFalse: [self sourceStringPrettifiedAndDiffed]
		ifTrue:	[ self commentContents])
			copy asText makeSelectorBoldIn: class! !


!Browser methodsFor: 'message list' stamp: 'jmv 4/7/2010 20:02'!
selectedMessage
	"Answer a copy of the source code for the selected message."

	| class selector method |
	contents
		ifNotNil: [^ contents copy].
	self showingDecompile ifTrue:
		[^ self decompiledSourceIntoContentsWithTempNames: false ].

	class _ self selectedClassOrMetaClass.
	selector _ self selectedMessageName.
	method _ class compiledMethodAt: selector ifAbsent: [^ ''].	"method deleted while in another project"
	currentCompiledMethod _ method.

	^ contents _ (self showingDocumentation
		ifFalse: [ self sourceStringPrettifiedAndDiffed ]
		ifTrue: [ self commentContents ])
			copy asText makeSelectorBoldIn: class! !


!Decompiler methodsFor: 'control' stamp: 'jmv 4/7/2010 21:25'!
doClosureCopyCopiedValues: blockCopiedValues numArgs: numArgs blockSize: blockSize
	| savedTemps savedTempVarCount savedNumLocalTemps
	  jump blockArgs blockTemps blockTempsOffset block |
	savedTemps _ tempVars.
	savedTempVarCount _ tempVarCount.
	savedNumLocalTemps _ numLocalTemps.
	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: 'arg', (tempVarCount + i) printString)
								  beBlockArg].
			blockTemps _ (1 to: numLocalTemps) collect:
							[:i| constructor
									codeTemp: i + blockTempsOffset - 1
									named: 'temp', (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).
	tempVars _ savedTemps.
	tempVarCount _ savedTempVarCount.
	numLocalTemps _ savedNumLocalTemps! !

!Decompiler methodsFor: 'instruction decoding' stamp: 'jmv 4/7/2010 21:25'!
popIntoTemporaryVariable: offset
	| maybeTVTag tempVector start |
	maybeTVTag _ stack last.
	((maybeTVTag isMemberOf: Association)
	 and: [maybeTVTag key == #pushNewArray]) ifTrue: [
		blockStartsToTempVars "implies we were intialized with temp names."
			ifNotNil: [ "Use the provided temps"
				self assert: ((tempVector _ tempVars at: offset + 1 ifAbsent: [ParseNode basicNew]) isTemp
							 and: [tempVector isIndirectTempVector
							 and: [tempVector remoteTemps size = maybeTVTag value size]])]
			ifNil: [ "Synthesize some remote temps"
				tempVector _ maybeTVTag value.
				offset + 1 <= tempVars size
					ifTrue: [
						start _ 2.
						tempVector at: 1 put: (tempVars at: offset + 1)]
					ifFalse: [
						tempVars _ (Array new: offset + 1)
										replaceFrom: 1
										to: tempVars size
										with: tempVars.
						start _ 1].
				start to: tempVector size do: [ :i |
					tempVector
						at: i
						put: (constructor
								codeTemp: numLocalTemps + offset + i - 1
								named: 'temp', (tempVarCount + i) printString)].
				tempVars at: offset + 1 put: (constructor codeRemoteTemp: offset + 1 remoteTemps: tempVector)].
		 tempVarCount _ tempVarCount + maybeTVTag value size.
		 stack removeLast.
		 ^self].
	self pushTemporaryVariable: offset; doStore: statements! !

!Decompiler methodsFor: 'initialize-release' stamp: 'jmv 4/7/2010 21:35'!
initSymbols: aClass
	| argCount |
	constructor method: method class: aClass literals: method literals.
	constTable _ constructor codeConstants.
	instVars _ Array new: aClass instSize.
	tempVarCount _ method numTemps.
	argCount _ method numArgs.
	"(tempVars isNil
	 and: [method holdsTempNames]) ifTrue:
		[tempVars := method tempNamesString]."
	tempVars isString
		ifTrue:
			[blockStartsToTempVars _ self mapFromBlockStartsIn: method
											toTempVarsFrom: tempVars
											constructor: constructor.
			 tempVars _ blockStartsToTempVars at: method initialPC]
		ifFalse:
			[| namedTemps |
			namedTemps _ tempVars ifNil: [(1 to: tempVarCount) collect: [ :i | 
					(i <= argCount ifTrue: ['arg'] ifFalse: ['temp']), i printString]].
			tempVars _ (1 to: tempVarCount) collect:
							[:i | i <= namedTemps size
								ifTrue: [constructor codeTemp: i - 1 named: (namedTemps at: i)]
								ifFalse: [constructor codeTemp: i - 1]]].
	1 to: method numArgs do:
		[:i|
		(tempVars at: i)
			beMethodArg]! !


!DecompilerConstructor methodsFor: 'constructor' stamp: 'jmv 4/7/2010 21:25'!
codeTemp: index

	^ TempVariableNode new
		name: 'temp' , (index + 1) printString
		index: index
		type: LdTempType
		scope: 0! !


!DecompilerConstructorForClosures methodsFor: 'constructor' stamp: 'jmv 4/7/2010 21:24'!
codeRemoteTemp: index remoteTemps: tempVector

	^(RemoteTempVectorNode new
		name: 'remoteVar', index printString
		index: index
		type: LdTempType
		scope: 0)
			remoteTemps: tempVector;
			yourself! !


!Encoder methodsFor: 'results' stamp: 'jmv 4/7/2010 21:45'!
tempNodes 
	| tempNodes |
	tempNodes _ SortedCollection sortBlock: [:n1 :n2 | n1 code <= n2 code].
	scopeTable associationsDo:
		[:assn |
		(assn value is: #Array)
			ifTrue: [assn value do: [:temp| tempNodes add: temp]]
			ifFalse: [assn value isTemp ifTrue: [tempNodes add: assn value]]].
	^tempNodes
	"jmv: perhaps better not include remote temps...
	^ tempNodes reject:
		[ : a |  a isUnusedTemp ]"! !


!MessageSet methodsFor: 'contents' stamp: 'jmv 4/7/2010 20:02'!
selectedMessage
	"Answer the source method for the currently selected message."

	| source |
	self setClassAndSelectorIn: [:class :selector | 
		class ifNil: [^ 'Class vanished'].
		selector first isUppercase ifTrue:
			[selector == #Comment ifTrue:
				[currentCompiledMethod _ class organization commentRemoteStr.
				^ class comment].
			selector == #Definition ifTrue:
				[^ class definition].
			selector == #Hierarchy ifTrue: [^ class printHierarchy]].
		source _ class sourceMethodAt: selector ifAbsent:
			[currentCompiledMethod _ nil.
			^ 'Missing'].

		self showingDecompile ifTrue:
			[^ self decompiledSourceIntoContentsWithTempNames: false ].

		currentCompiledMethod _ class compiledMethodAt: selector ifAbsent: nil.
		self showingDocumentation ifTrue:
			[^ self commentContents].

	source _ self sourceStringPrettifiedAndDiffed.
	^ source asText makeSelectorBoldIn: class]! !


!MethodHolder methodsFor: 'contents' stamp: 'jmv 4/7/2010 20:02'!
stringContents
	"Answer the contents, with due respect for my contentsSymbol"

	contents _ methodClass sourceCodeAt: methodSelector ifAbsent: [''].
	currentCompiledMethod _ methodClass compiledMethodAt: methodSelector ifAbsent: nil.

	self showingDecompile ifTrue: [
		^ self decompiledSourceIntoContentsWithTempNames: false ].

	self showingDocumentation ifTrue: [
		^ self commentContents].

	^ contents _ self sourceStringPrettifiedAndDiffed asText makeSelectorBoldIn: methodClass! !

