|  | @@ -1517,7 +1517,7 @@ performOptimizations: aBoolean
 | 
	
		
			
				|  |  |  ! !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  AbstractCodeGenerator subclass: #ImpCodeGenerator
 | 
	
		
			
				|  |  | -	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables ivarAliases toIvar mutables assigned'
 | 
	
		
			
				|  |  | +	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables mutables assigned target lazyVars'
 | 
	
		
			
				|  |  |  	package: 'Compiler'!
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  !ImpCodeGenerator methodsFor: 'accessing'!
 | 
	
	
		
			
				|  | @@ -1548,8 +1548,8 @@ alias: aString
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  alias: aString mutable: aBoolean
 | 
	
		
			
				|  |  | -	(ivarAliases includesKey: toIvar)
 | 
	
		
			
				|  |  | -		ifTrue: [ ivarAliases at: toIvar put: aString. aBoolean ifTrue: [ mutables add: toIvar ] ]
 | 
	
		
			
				|  |  | +	(lazyVars includesKey: target)
 | 
	
		
			
				|  |  | +		ifTrue: [ lazyVars at: target put: aString. aBoolean ifTrue: [ mutables add: target ] ]
 | 
	
		
			
				|  |  |  		ifFalse: [ self assign: aString ]
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1562,10 +1562,10 @@ assign: aString
 | 
	
		
			
				|  |  |  	aString ifNotEmpty: [
 | 
	
		
			
				|  |  |  		self disarmAll.
 | 
	
		
			
				|  |  |  		closer := ''.
 | 
	
		
			
				|  |  | -		toIvar ifNotNil: [ stream nextPutAll:
 | 
	
		
			
				|  |  | -			(toIvar = '^' ifTrue: ['return '] ifFalse: [
 | 
	
		
			
				|  |  | -				toIvar = '!!' ifTrue: [ closer := ']'. 'throw $early=['] ifFalse: [
 | 
	
		
			
				|  |  | -					toIvar, '=']]) ].
 | 
	
		
			
				|  |  | +		self ifValueWanted: [ stream nextPutAll:
 | 
	
		
			
				|  |  | +			(target = '^' ifTrue: ['return '] ifFalse: [
 | 
	
		
			
				|  |  | +				target = '!!' ifTrue: [ closer := ']'. 'throw $early=['] ifFalse: [
 | 
	
		
			
				|  |  | +					target, '=']]) ].
 | 
	
		
			
				|  |  |  		self makeAssigned.
 | 
	
		
			
				|  |  |  		stream nextPutAll: aString, closer, ';', self mylf ]
 | 
	
		
			
				|  |  |  !
 | 
	
	
		
			
				|  | @@ -1574,79 +1574,73 @@ disarmAll
 | 
	
		
			
				|  |  |  | list old |
 | 
	
		
			
				|  |  |  	list := mutables.
 | 
	
		
			
				|  |  |  	mutables := Set new.
 | 
	
		
			
				|  |  | -	old := toIvar.
 | 
	
		
			
				|  |  | +	old := self switchTarget: nil.
 | 
	
		
			
				|  |  |  	list do: [ :each | | value |
 | 
	
		
			
				|  |  | -		toIvar := each.
 | 
	
		
			
				|  |  | -		value := ivarAliases at: each.
 | 
	
		
			
				|  |  | -		self assign: value
 | 
	
		
			
				|  |  | +		self switchTarget: each.
 | 
	
		
			
				|  |  | +		self assign: (lazyVars at: each)
 | 
	
		
			
				|  |  |  	].
 | 
	
		
			
				|  |  | -	toIvar := old
 | 
	
		
			
				|  |  | +	self switchTarget: old
 | 
	
		
			
				|  |  | +!
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +ifValueWanted: aBlock
 | 
	
		
			
				|  |  | +	target ifNotNil: aBlock
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  isolate: aBlock
 | 
	
		
			
				|  |  | -| old ivar |
 | 
	
		
			
				|  |  | -	old := toIvar.
 | 
	
		
			
				|  |  | -	ivar := toIvar := self nextIvar.
 | 
	
		
			
				|  |  | +| old |
 | 
	
		
			
				|  |  | +	old := self switchTarget: self nextLazyvarName.
 | 
	
		
			
				|  |  |  	aBlock value.
 | 
	
		
			
				|  |  | -	toIvar := old.
 | 
	
		
			
				|  |  | -	^ivar
 | 
	
		
			
				|  |  | +	^self switchTarget: old
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  isolated: node
 | 
	
		
			
				|  |  | - 	^ self visit: node ivar: self nextIvar
 | 
	
		
			
				|  |  | + 	^ self visit: node targetBeing: self nextLazyvarName
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  isolatedUse: node
 | 
	
		
			
				|  |  | -| old operand |
 | 
	
		
			
				|  |  | -	old := toIvar.
 | 
	
		
			
				|  |  | -	toIvar := self nextIvar.
 | 
	
		
			
				|  |  | +| old |
 | 
	
		
			
				|  |  | +	old := self switchTarget: self nextLazyvarName.
 | 
	
		
			
				|  |  |  	self visit: node.
 | 
	
		
			
				|  |  | -	operand := self useIvar.
 | 
	
		
			
				|  |  | -	toIvar := old.
 | 
	
		
			
				|  |  | -	^operand
 | 
	
		
			
				|  |  | +	^self useValueNamed: (self switchTarget: old)
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  makeAssigned
 | 
	
		
			
				|  |  | -	(ivarAliases includesKey: toIvar) ifTrue: [
 | 
	
		
			
				|  |  | -		ivarAliases removeKey: toIvar.
 | 
	
		
			
				|  |  | -		ivarAliases at: 'assigned ',toIvar put: nil.
 | 
	
		
			
				|  |  | -		assigned add: toIvar ].
 | 
	
		
			
				|  |  | +	(lazyVars includesKey: target) ifTrue: [
 | 
	
		
			
				|  |  | +		lazyVars removeKey: target.
 | 
	
		
			
				|  |  | +		lazyVars at: 'assigned ',target put: nil. "<-- only to retain size, it is used in nextLazyvarName"
 | 
	
		
			
				|  |  | +		assigned add: target ].
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -nextIvar
 | 
	
		
			
				|  |  | +nextLazyvarName
 | 
	
		
			
				|  |  |  	| name |
 | 
	
		
			
				|  |  | -	name := '$', ivarAliases size asString.
 | 
	
		
			
				|  |  | -	ivarAliases at: name put: name.
 | 
	
		
			
				|  |  | +	name := '$', lazyVars size asString.
 | 
	
		
			
				|  |  | +	lazyVars at: name put: name.
 | 
	
		
			
				|  |  |  	^name
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -useIvar
 | 
	
		
			
				|  |  | -	^self useIvarIfAbsent: [ self error: 'Absent ivar: ', toIvar ]
 | 
	
		
			
				|  |  | +nilIfValueWanted
 | 
	
		
			
				|  |  | +	target ifNotNil: [ self alias: 'nil' ]
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -useIvar: ivar
 | 
	
		
			
				|  |  | -| old result |
 | 
	
		
			
				|  |  | -	old := toIvar.
 | 
	
		
			
				|  |  | -	toIvar := ivar.
 | 
	
		
			
				|  |  | -	result := self useIvar.
 | 
	
		
			
				|  |  | -	toIvar := old.
 | 
	
		
			
				|  |  | -	^ result
 | 
	
		
			
				|  |  | +switchTarget: aString
 | 
	
		
			
				|  |  | +	| old |
 | 
	
		
			
				|  |  | +	old := target.
 | 
	
		
			
				|  |  | +	target := aString.
 | 
	
		
			
				|  |  | +	^old
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -useIvarIfAbsent: aBlock
 | 
	
		
			
				|  |  | -| val |
 | 
	
		
			
				|  |  | -	(assigned includes: toIvar) ifTrue: [ ^toIvar ].
 | 
	
		
			
				|  |  | -	mutables remove: toIvar.
 | 
	
		
			
				|  |  | -	^ivarAliases at: toIvar ifAbsent: aBlock
 | 
	
		
			
				|  |  | +useValueNamed: key
 | 
	
		
			
				|  |  | +	| val |
 | 
	
		
			
				|  |  | +	(assigned includes: key) ifTrue: [ ^key ].
 | 
	
		
			
				|  |  | +	mutables remove: key.
 | 
	
		
			
				|  |  | +	^lazyVars at: key
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -visit: aNode ivar: aString
 | 
	
		
			
				|  |  | +visit: aNode targetBeing: aString
 | 
	
		
			
				|  |  |  | old |
 | 
	
		
			
				|  |  | -	old := toIvar.
 | 
	
		
			
				|  |  | -	toIvar := aString.
 | 
	
		
			
				|  |  | +	old := self switchTarget: aString.
 | 
	
		
			
				|  |  |  	self visit: aNode.
 | 
	
		
			
				|  |  | -	toIvar := old.
 | 
	
		
			
				|  |  | -	^ aString
 | 
	
		
			
				|  |  | +	^ self switchTarget: old.
 | 
	
		
			
				|  |  |  ! !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  !ImpCodeGenerator methodsFor: 'compiling'!
 | 
	
	
		
			
				|  | @@ -1669,8 +1663,8 @@ initialize
 | 
	
		
			
				|  |  |  	classReferenced := #().
 | 
	
		
			
				|  |  |  	mutables := Set new.
 | 
	
		
			
				|  |  |  	assigned := Set new.
 | 
	
		
			
				|  |  | -	ivarAliases := HashedCollection new.
 | 
	
		
			
				|  |  | -	toIvar := nil
 | 
	
		
			
				|  |  | +	lazyVars := HashedCollection new.
 | 
	
		
			
				|  |  | +	target := nil
 | 
	
		
			
				|  |  |  ! !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  !ImpCodeGenerator methodsFor: 'optimizations'!
 | 
	
	
		
			
				|  | @@ -1682,7 +1676,7 @@ checkClass: aClassName for: receiver
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  checkClass: aClassName for: receiver includeIf: aBoolean
 | 
	
		
			
				|  |  |  	self prvCheckClass: aClassName for: receiver.
 | 
	
		
			
				|  |  | -	stream nextPutAll: (aBoolean ifTrue: ['if(('] ifFalse: ['if(!!(']), (self useIvar: receiver), ')) {'
 | 
	
		
			
				|  |  | +	stream nextPutAll: (aBoolean ifTrue: ['if(('] ifFalse: ['if(!!(']), (self useValueNamed: receiver), ')) {'
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  inline: aSelector receiver: receiver argumentNodes: aCollection
 | 
	
	
		
			
				|  | @@ -1693,14 +1687,14 @@ inline: aSelector receiver: receiver argumentNodes: aCollection
 | 
	
		
			
				|  |  |  		aCollection first isBlockNode ifTrue: [
 | 
	
		
			
				|  |  |  			self checkClass: 'Boolean' for: receiver includeIf: false.
 | 
	
		
			
				|  |  |  			self prvPutAndElse: [ self visit: aCollection first nodes first ].
 | 
	
		
			
				|  |  | -			self prvPutAndElse: [ toIvar ifNotNil: [ self aliasMutable: 'nil' ] ].
 | 
	
		
			
				|  |  | +			self prvPutAndElse: [ self nilIfValueWanted ].
 | 
	
		
			
				|  |  |  			^true]].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = 'ifTrue:') ifTrue: [
 | 
	
		
			
				|  |  |  		aCollection first isBlockNode ifTrue: [
 | 
	
		
			
				|  |  |  			self checkClass: 'Boolean' for: receiver includeIf: true.
 | 
	
		
			
				|  |  |  			self prvPutAndElse: [ self visit: aCollection first nodes first ].
 | 
	
		
			
				|  |  | -			self prvPutAndElse: [ toIvar ifNotNil: [ self aliasMutable: 'nil' ] ].
 | 
	
		
			
				|  |  | +			self prvPutAndElse: [ self nilIfValueWanted ].
 | 
	
		
			
				|  |  |  			^true]].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
 | 
	
	
		
			
				|  | @@ -1723,56 +1717,56 @@ inline: aSelector receiver: receiver argumentNodes: aCollection
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '<', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '<', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = '<=') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '<=', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '<=', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = '>') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '>', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '>', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = '>=') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '>=', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '>=', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          (aSelector = '+') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '+', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '+', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          (aSelector = '-') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '-', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '-', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          (aSelector = '*') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '*', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '*', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          (aSelector = '/') ifTrue: [ | operand |
 | 
	
		
			
				|  |  |  		operand := self isolatedUse: aCollection first.
 | 
	
		
			
				|  |  |  		self checkClass: 'Number' for: receiver.
 | 
	
		
			
				|  |  |  		self prvPutAndElse: [
 | 
	
		
			
				|  |  | -			self aliasMutable: '(', (self useIvar: receiver), '/', operand, ')' ].
 | 
	
		
			
				|  |  | +			self aliasMutable: '(', (self useValueNamed: receiver), '/', operand, ')' ].
 | 
	
		
			
				|  |  |  		^{ VerbatimNode new value: operand }].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          ^nil
 | 
	
	
		
			
				|  | @@ -1788,14 +1782,14 @@ inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
 | 
	
		
			
				|  |  |            	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
 | 
	
		
			
				|  |  |  			self prvWhileConditionStatement: 'for(;;){' pre: 'if (!!(' condition: anObject post: ')) {'.
 | 
	
		
			
				|  |  |  			stream nextPutAll: 'break}', self mylf.
 | 
	
		
			
				|  |  | -			self prvPutAndClose: [ self visit: aCollection first nodes first ivar: nil ].
 | 
	
		
			
				|  |  | +			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
 | 
	
		
			
				|  |  |  			inlined := true]].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = 'whileFalse:') ifTrue: [
 | 
	
		
			
				|  |  |            	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
 | 
	
		
			
				|  |  |  			self prvWhileConditionStatement: 'for(;;){' pre: 'if ((' condition: anObject post: ')) {'.
 | 
	
		
			
				|  |  |  			stream nextPutAll: 'break}', self mylf.
 | 
	
		
			
				|  |  | -			self prvPutAndClose: [ self visit: aCollection first nodes first ivar: nil ].
 | 
	
		
			
				|  |  | +			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
 | 
	
		
			
				|  |  |  			inlined := true]].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	(aSelector = 'whileTrue') ifTrue: [
 | 
	
	
		
			
				|  | @@ -1884,7 +1878,7 @@ isNode: aNode ofClass: aClass
 | 
	
		
			
				|  |  |  prvCheckClass: aClassName for: receiver
 | 
	
		
			
				|  |  |  	self makeAssigned.
 | 
	
		
			
				|  |  |  	self disarmAll.
 | 
	
		
			
				|  |  | -        stream nextPutAll: 'if((', (self useIvar: receiver), ').klass === smalltalk.', aClassName, ') '
 | 
	
		
			
				|  |  | +        stream nextPutAll: 'if((', (self useValueNamed: receiver), ').klass === smalltalk.', aClassName, ') '
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  prvInlineNumberOperator: aSelector on: receiverNode and: operandNode
 | 
	
	
		
			
				|  | @@ -1893,7 +1887,7 @@ prvInlineNumberOperator: aSelector on: receiverNode and: operandNode
 | 
	
		
			
				|  |  |  			| rcv operand |
 | 
	
		
			
				|  |  |  			rcv := self isolated: receiverNode.
 | 
	
		
			
				|  |  |  			operand := self isolated: operandNode.
 | 
	
		
			
				|  |  | -			self alias: ((self useIvar: rcv), aSelector, (self useIvar: operand)).
 | 
	
		
			
				|  |  | +			self alias: ((self useValueNamed: rcv), aSelector, (self useValueNamed: operand)).
 | 
	
		
			
				|  |  |  			^true]].
 | 
	
		
			
				|  |  |  	^false
 | 
	
		
			
				|  |  |  !
 | 
	
	
		
			
				|  | @@ -1904,7 +1898,7 @@ prvWhileConditionStatement: stmtString pre: preString condition: anObject post:
 | 
	
		
			
				|  |  |  	x := self isolatedUse: anObject nodes first.
 | 
	
		
			
				|  |  |  	x ifEmpty: [ x := '"should not reach - receiver includes ^"' ].
 | 
	
		
			
				|  |  |  	stream nextPutAll: preString, x, postString.
 | 
	
		
			
				|  |  | -	toIvar ifNotNil: [ self alias: 'nil' ]
 | 
	
		
			
				|  |  | +	self nilIfValueWanted
 | 
	
		
			
				|  |  |  ! !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  !ImpCodeGenerator methodsFor: 'output'!
 | 
	
	
		
			
				|  | @@ -1954,7 +1948,7 @@ arrayOfValues: nodes
 | 
	
		
			
				|  |  |  	self alias: (String streamContents: [ :str |
 | 
	
		
			
				|  |  |  		str nextPutAll: '['.
 | 
	
		
			
				|  |  |  		args
 | 
	
		
			
				|  |  | -	    		do: [:each | str nextPutAll: (self useIvar: each) ]
 | 
	
		
			
				|  |  | +	    		do: [:each | str nextPutAll: (self useValueNamed: each) ]
 | 
	
		
			
				|  |  |  	    		separatedBy: [str nextPutAll: ', '].
 | 
	
		
			
				|  |  |                  str nextPutAll: ']'
 | 
	
		
			
				|  |  |  	])
 | 
	
	
		
			
				|  | @@ -1965,9 +1959,9 @@ send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
 | 
	
		
			
				|  |  |  	args := self isolate: [ self arrayOfValues: aCollection ].
 | 
	
		
			
				|  |  |  	self aliasMutable: (String streamContents: [ :str |
 | 
	
		
			
				|  |  |  		str nextPutAll: 'smalltalk.send('.
 | 
	
		
			
				|  |  | -		str nextPutAll: (self useIvar: aReceiver).
 | 
	
		
			
				|  |  | +		str nextPutAll: (self useValueNamed: aReceiver).
 | 
	
		
			
				|  |  |  		str nextPutAll: ', "', aSelector asSelector, '", '.
 | 
	
		
			
				|  |  | -		str nextPutAll: (self useIvar: args).
 | 
	
		
			
				|  |  | +		str nextPutAll: (self useValueNamed: args).
 | 
	
		
			
				|  |  |  		aBoolean ifTrue: [
 | 
	
		
			
				|  |  |  			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
 | 
	
		
			
				|  |  |  		str nextPutAll: ')'
 | 
	
	
		
			
				|  | @@ -1978,14 +1972,13 @@ sequenceOfNodes: nodes temps: temps
 | 
	
		
			
				|  |  |  	nodes isEmpty
 | 
	
		
			
				|  |  |  		ifFalse: [ | old index |
 | 
	
		
			
				|  |  |  			self putTemps: temps.
 | 
	
		
			
				|  |  | -			old := toIvar.
 | 
	
		
			
				|  |  | -			toIvar := nil.
 | 
	
		
			
				|  |  | +			old :=self switchTarget: nil.
 | 
	
		
			
				|  |  |  			index := 0.
 | 
	
		
			
				|  |  |  			nodes do: [:each |
 | 
	
		
			
				|  |  |  				index := index + 1.
 | 
	
		
			
				|  |  | -				index = nodes size ifTrue: [ toIvar := old ].
 | 
	
		
			
				|  |  | +				index = nodes size ifTrue: [ self switchTarget: old ].
 | 
	
		
			
				|  |  |  			self visit: each ]]
 | 
	
		
			
				|  |  | -		ifTrue: [ toIvar ifNotNil: [ self alias: 'nil' ]]
 | 
	
		
			
				|  |  | +		ifTrue: [ self nilIfValueWanted ]
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  visit: aNode
 | 
	
	
		
			
				|  | @@ -1995,25 +1988,22 @@ visit: aNode
 | 
	
		
			
				|  |  |  visitAssignmentNode: aNode
 | 
	
		
			
				|  |  |  | olds oldt |
 | 
	
		
			
				|  |  |  	olds := stream.
 | 
	
		
			
				|  |  | -	oldt := toIvar.
 | 
	
		
			
				|  |  |  	stream := '' writeStream.
 | 
	
		
			
				|  |  | -	toIvar := self nextIvar.
 | 
	
		
			
				|  |  | +	oldt := self switchTarget: self nextLazyvarName.
 | 
	
		
			
				|  |  |  	self visit: aNode left.
 | 
	
		
			
				|  |  | -	self assert: (ivarAliases at: toIvar) ~= toIvar.
 | 
	
		
			
				|  |  | -	toIvar := self useIvar.
 | 
	
		
			
				|  |  | -	self assert: (ivarAliases includesKey: toIvar) not.
 | 
	
		
			
				|  |  | +	self assert: (lazyVars at: target) ~= target.
 | 
	
		
			
				|  |  | +	self switchTarget: (self useValueNamed: (self switchTarget: nil)).
 | 
	
		
			
				|  |  | +	self assert: (lazyVars includesKey: target) not.
 | 
	
		
			
				|  |  |  	stream := olds.
 | 
	
		
			
				|  |  |  	self visit: aNode right.
 | 
	
		
			
				|  |  | -	olds := toIvar.
 | 
	
		
			
				|  |  | -	toIvar := oldt.
 | 
	
		
			
				|  |  | -	toIvar ifNotNil: [ self aliasMutable: olds ]
 | 
	
		
			
				|  |  | +	olds := self switchTarget: oldt.
 | 
	
		
			
				|  |  | +	self ifValueWanted: [ self aliasMutable: olds ]
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  visitBlockNode: aNode
 | 
	
		
			
				|  |  |  | oldt olds oldm |
 | 
	
		
			
				|  |  |  	self assert: aNode nodes size = 1.
 | 
	
		
			
				|  |  | -	oldt := toIvar.
 | 
	
		
			
				|  |  | -	toIvar := '^'.
 | 
	
		
			
				|  |  | +	oldt := self switchTarget: '^'.
 | 
	
		
			
				|  |  |  	olds := stream.
 | 
	
		
			
				|  |  |  	stream := '' writeStream.
 | 
	
		
			
				|  |  |  	stream nextPutAll: '(function('.
 | 
	
	
		
			
				|  | @@ -2031,7 +2021,7 @@ visitBlockNode: aNode
 | 
	
		
			
				|  |  |  	mutables := oldm.
 | 
	
		
			
				|  |  |  	nestedBlocks := nestedBlocks - 1.
 | 
	
		
			
				|  |  |  	stream nextPutAll: '})'.
 | 
	
		
			
				|  |  | -	toIvar := oldt.
 | 
	
		
			
				|  |  | +	self switchTarget: oldt.
 | 
	
		
			
				|  |  |  	oldt := stream contents.
 | 
	
		
			
				|  |  |  	stream := olds.
 | 
	
		
			
				|  |  |  	self aliasMutable: oldt
 | 
	
	
		
			
				|  | @@ -2045,7 +2035,7 @@ visitCascadeNode: aNode
 | 
	
		
			
				|  |  |  	| rcv |
 | 
	
		
			
				|  |  |  	rcv := self isolated: aNode receiver.
 | 
	
		
			
				|  |  |  	self disarmAll.
 | 
	
		
			
				|  |  | -	rcv := self useIvar: rcv.
 | 
	
		
			
				|  |  | +	rcv := self useValueNamed: rcv.
 | 
	
		
			
				|  |  |  	aNode nodes do: [:each |
 | 
	
		
			
				|  |  |  		each receiver: (VerbatimNode new value: rcv) ].
 | 
	
		
			
				|  |  |  	self sequenceOfNodes: aNode nodes temps: #()
 | 
	
	
		
			
				|  | @@ -2064,7 +2054,7 @@ visitDynamicArrayNode: aNode
 | 
	
		
			
				|  |  |  visitDynamicDictionaryNode: aNode
 | 
	
		
			
				|  |  |  	| elements |
 | 
	
		
			
				|  |  |  	elements := self isolate: [ self arrayOfValues: aNode nodes ].
 | 
	
		
			
				|  |  | -	self alias: 'smalltalk.HashedCollection._fromPairs_(', (self useIvar: elements), ')'
 | 
	
		
			
				|  |  | +	self alias: 'smalltalk.HashedCollection._fromPairs_(', (self useValueNamed: elements), ')'
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  visitFailure: aFailure
 | 
	
	
		
			
				|  | @@ -2086,7 +2076,7 @@ visitMethodNode: aNode
 | 
	
		
			
				|  |  |  	unknownVariables := #().
 | 
	
		
			
				|  |  |  	tempVariables := #().
 | 
	
		
			
				|  |  |  	argVariables := #().
 | 
	
		
			
				|  |  | -	ivarAliases := HashedCollection new.
 | 
	
		
			
				|  |  | +	lazyVars := HashedCollection new.
 | 
	
		
			
				|  |  |  	mutables := Set new.
 | 
	
		
			
				|  |  |  	assigned := Set new.
 | 
	
		
			
				|  |  |  	stream 
 | 
	
	
		
			
				|  | @@ -2103,7 +2093,7 @@ visitMethodNode: aNode
 | 
	
		
			
				|  |  |  	    nextPutAll: '){var self=this;', self mylf.
 | 
	
		
			
				|  |  |  	str := stream.
 | 
	
		
			
				|  |  |  	stream := '' writeStream.
 | 
	
		
			
				|  |  | -	toIvar := nil.
 | 
	
		
			
				|  |  | +	self switchTarget: nil.
 | 
	
		
			
				|  |  |  	self assert: aNode nodes size = 1.
 | 
	
		
			
				|  |  |  	self visit: aNode nodes first.
 | 
	
		
			
				|  |  |  	assigned ifNotEmpty: [ str nextPutAll: 'var ', (assigned asArray join: ','), ';', self mylf ].
 | 
	
	
		
			
				|  | @@ -2114,7 +2104,7 @@ visitMethodNode: aNode
 | 
	
		
			
				|  |  |  	(aNode nodes first nodes notEmpty and: [ |checker|
 | 
	
		
			
				|  |  |  	    checker := ReturnNodeChecker new.
 | 
	
		
			
				|  |  |  	    checker visit: aNode nodes first nodes last.
 | 
	
		
			
				|  |  | -	    checker wasReturnNode]) ifFalse: [ toIvar := '^'. self alias: 'self'. toIvar := nil ].
 | 
	
		
			
				|  |  | +	    checker wasReturnNode]) ifFalse: [ self switchTarget: '^'. self alias: 'self'. self switchTarget: nil ].
 | 
	
		
			
				|  |  |  	earlyReturn ifTrue: [
 | 
	
		
			
				|  |  |  	    stream nextPutAll: '} catch(e) {if(e===$early) return e[0]; throw e}'].
 | 
	
		
			
				|  |  |  	stream nextPutAll: '}'.
 | 
	
	
		
			
				|  | @@ -2137,7 +2127,7 @@ visitReturnNode: aNode
 | 
	
		
			
				|  |  |  	    earlyReturn := true].
 | 
	
		
			
				|  |  |  	self
 | 
	
		
			
				|  |  |  		visit: aNode nodes first
 | 
	
		
			
				|  |  | -		ivar: (nestedBlocks > 0 ifTrue: ['!!'] ifFalse: ['^']).
 | 
	
		
			
				|  |  | +		targetBeing: (nestedBlocks > 0 ifTrue: ['!!'] ifFalse: ['^']).
 | 
	
		
			
				|  |  |  	self alias: ''
 | 
	
		
			
				|  |  |  !
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2152,8 +2142,8 @@ visitSendNode: aNode
 | 
	
		
			
				|  |  |  		].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	rcv := self isolated: aNode receiver.
 | 
	
		
			
				|  |  | -        superSend := (ivarAliases at: rcv ifAbsent: []) = 'super'.
 | 
	
		
			
				|  |  | -        superSend ifTrue: [ mutables remove: rcv. ivarAliases at: rcv put: 'self' ].
 | 
	
		
			
				|  |  | +        superSend := (lazyVars at: rcv ifAbsent: []) = 'super'.
 | 
	
		
			
				|  |  | +        superSend ifTrue: [ mutables remove: rcv. lazyVars at: rcv put: 'self' ].
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	self performOptimizations 
 | 
	
		
			
				|  |  |  		ifTrue: [ | inline |
 |