[squeak-dev] The Inbox: Compiler-eem.421.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Mar 26 04:00:39 UTC 2020


A new version of Compiler was added to project The Inbox:
http://source.squeak.org/inbox/Compiler-eem.421.mcz

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

Name: Compiler-eem.421
Author: eem
Time: 25 March 2020, 9:00:37.328826 pm
UUID: 7bacb14a-f088-4fca-aa94-35dae28aa8e8
Ancestors: Compiler-nice.420

A suggested implementation of writable results from doits.  This scheme is careful to only make read-only collection literals that the compiler makes read-only, not e.g. numeric literals (which should always be read-only) or objects the evaluation makes read-only.

=============== Diff against Compiler-nice.420 ===============

Item was changed:
  Object subclass: #CompilationCue
+ 	instanceVariableNames: 'source context receiver class environment requestor writableCollectionLiterals'
- 	instanceVariableNames: 'source context receiver class environment requestor'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Compiler-Kernel'!
  
+ !CompilationCue commentStamp: 'eem 3/25/2020 20:52' prior: 0!
- !CompilationCue commentStamp: 'eem 3/30/2017 17:32' prior: 0!
  A CompilationCue is a helper class holding enough context for evaluating/compiling Smalltalk code.
  
  That is mainly the source code, and the source code editor to interact with if the Compiler is used interactively.
  But that is also any additional information necessary to resolve variable names.
  
  When compiling a method, the Compiler typically need to know the target class in which to install the method.
  
  When evaluating an expression, the Compiler also needs a receiver (for accessing the value of its instance variables), its class (for resolving instance/class variable names), and optionnally a context of execution when debugging a method (for accessing values of temporaries and parameters).
  
  Instance Variables
+ 	class:						<Behavior>
+ 	context:					<Context | nil>
+ 	environment: 				<Environment | nil>
+ 	receiver:					<Object>
+ 	requestor:					<TextEditor | nil>
+ 	source:						<Stream>
+ 	writableCollectionLiterals:	<Boolean>
- 	class:			<Behavior>
- 	context:		<Context | nil>
- 	environment:	<Environment | nil>
- 	receiver:		<Object>
- 	requestor:		<TextEditor | nil>
- 	source:			<Stream>
  
  class
  	- the target class in which to install the compiled method;
  	  this enables to resolve the instance variable names, class variable names and shared pool variable names.
  	  When evaluating, this should be the receiver class
  
  context
  	- the context introspected when evaluating the code: this is typically for accessing parameters and temporary variables when debugging
  
  environment
  	- the environment in which to resolve global variable names
  
  receiver
  	- the receiver into which to evaluate the code: this is typically for accessing instance variables in an inspector
  
  requestor
  	- typically the text editor containing the source code being compiled/evaluated. This enables the Compiler to interact in case of syntax error.
  
  source
  	- a ReadStream on the source code to be compiled
+ 
+ writableCollectionLiterals
+ 	- if true then the compiler should answer writable collection literals in an evaluation; by default all literals are read-only
  !

Item was changed:
  ----- Method: CompilationCue class>>source:context:class:environment:requestor: (in category 'instance creation') -----
  source: aTextOrStream context: aContext class: aClass environment: anEnvironment requestor: reqObject
  	^ self basicNew
  		initializeWithSource: aTextOrStream 
  		context: aContext 
  		receiver: (aContext ifNotNil: [aContext receiver]) 
  		class: aClass 
  		environment: anEnvironment 
+ 		requestor: reqObject
+ 		writableCollectionLiterals: false!
- 		requestor: reqObject!

Item was changed:
  ----- Method: CompilationCue class>>source:context:receiver:class:environment:requestor: (in category 'instance creation') -----
  source: aTextOrStream context: aContext receiver: recObject class: aClass environment: anEnvironment requestor: reqObject
  	^ self basicNew
  		initializeWithSource: aTextOrStream 
  		context: aContext 
  		receiver: recObject 
  		class: aClass 
  		environment: anEnvironment 
+ 		requestor: reqObject
+ 		writableCollectionLiterals: false!
- 		requestor: reqObject!

Item was added:
+ ----- Method: CompilationCue class>>source:context:receiver:class:environment:requestor:writableCollectionLiterals: (in category 'instance creation') -----
+ source: aTextOrStream context: aContext receiver: recObject class: aClass environment: anEnvironment requestor: reqObject writableCollectionLiterals: writableCollectionLiteralsBool
+ 	^ self basicNew
+ 		initializeWithSource: aTextOrStream 
+ 		context: aContext 
+ 		receiver: recObject 
+ 		class: aClass 
+ 		environment: anEnvironment 
+ 		requestor: reqObject
+ 		writableCollectionLiterals: writableCollectionLiteralsBool!

Item was added:
+ ----- Method: CompilationCue class>>source:writableCollectionLiterals:environment: (in category 'instance creation') -----
+ source: aString writableCollectionLiterals: writableCollectionLiterals environment: anEnvironment
+ 	^ self 
+ 		source: aString
+ 		context: nil
+ 		receiver: nil
+ 		class: UndefinedObject
+ 		environment: anEnvironment
+ 		requestor: nil
+ 		writableCollectionLiterals: writableCollectionLiterals!

Item was removed:
- ----- Method: CompilationCue>>initializeWithSource:context:receiver:class:environment:requestor: (in category 'initialization') -----
- initializeWithSource: aTextOrString context: aContext receiver: recObject class: aClass environment: anEnvironment requestor: reqObject
- 	self initialize.
- 	source := (aTextOrString isKindOf: PositionableStream)
- 		ifTrue: [ aTextOrString ]
- 		ifFalse: [ ReadStream on: aTextOrString asString ].
- 	context := aContext.
- 	receiver := recObject.
- 	class := aClass.
- 	environment := anEnvironment.
- 	requestor := reqObject!

Item was added:
+ ----- Method: CompilationCue>>initializeWithSource:context:receiver:class:environment:requestor:writableCollectionLiterals: (in category 'initialization') -----
+ initializeWithSource: aTextOrString context: aContext receiver: recObject class: aClass environment: anEnvironment requestor: reqObject writableCollectionLiterals: writableCollectionLiteralsBool
+ 	self initialize.
+ 	source := aTextOrString isStream
+ 		ifTrue: [ aTextOrString ]
+ 		ifFalse: [ ReadStream on: aTextOrString asString ].
+ 	context := aContext.
+ 	receiver := recObject.
+ 	class := aClass.
+ 	environment := anEnvironment.
+ 	requestor := reqObject.
+ 	writableCollectionLiterals := writableCollectionLiteralsBool!

Item was added:
+ ----- Method: CompilationCue>>writableCollectionLiterals (in category 'accessing') -----
+ writableCollectionLiterals
+ 	^writableCollectionLiterals!

Item was added:
+ ----- Method: Compiler class>>evaluate:writableCollectionLiterals:environment: (in category 'evaluating') -----
+ evaluate: aString writableCollectionLiterals: writableCollectionLiteralsBool environment: anEnvironment
+ 	^  self new
+ 		evaluateCue: (CompilationCue
+ 			source: aString
+ 			writableCollectionLiterals: writableCollectionLiteralsBool
+ 			environment: anEnvironment)
+ 		ifFail: [^ nil]!

Item was changed:
  ----- Method: Compiler>>evaluateCue:ifFail: (in category 'private') -----
  evaluateCue: aCue ifFail: failBlock
  	"Compiles the cue source into a parse tree, then generates code into
  	a method. Finally, the compiled method is invoked from here via 	withArgs:executeMethod:, hence the system no longer creates Doit method
  	litter on errors."
  
  	| methodNode method value |
  	methodNode := self compileCue: aCue noPattern: true ifFail: [^failBlock value].
  
  	method := self interactive
  				ifTrue: [methodNode generateWithTempNames]
  				ifFalse: [methodNode generate].
  
  	value := cue receiver
  				withArgs: (cue context ifNil: [#()] ifNotNil: [{cue context}])
  				executeMethod: method.
+ 	cue writableCollectionLiterals ifTrue:
+ 		[method allLiteralsDo:
+ 			[:lit| self makeCollectionLiteralWritable: lit]].
  	^ value
  !

Item was added:
+ ----- Method: Compiler>>makeCollectionLiteralWritable: (in category 'private') -----
+ makeCollectionLiteralWritable: lit
+ 	"By default all literals are read-only.  Usually this is exactly what we desire.
+ 	 Sometimes this is inconvenient.  This method makes collection literals, and
+ 	 only collection literals, writable, in response to the writableCollectionLiterals cue"
+ 	lit isCollection ifTrue:
+ 		[lit beWritableObject.
+ 		 lit isArray ifTrue:
+ 			[lit do:
+ 				[:subLiteral| self makeCollectionLiteralWritable: subLiteral]]]!



More information about the Squeak-dev mailing list