Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate ReadOnly EnvInObj handlers #6

Open
wants to merge 1 commit into
base: reflectiveCompiler
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Examples/Benchmarks/Mate/Immutability/HandlesEnvInObj/Handle.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Handle = (
| target |
"Accessing"
targetSPECIAL: anObject = ( target := anObject )
targetSPECIAL = ( ^target )
= other = (^self equalsSPECIAL: other)
equalsSPECIAL: other = (^target = other)
== other = (^self equalsequalsSPECIAL: other)
equalsequalsSPECIAL: other = (
| compareTo |
compareTo := (other class = self class)
ifTrue: [other targetSPECIAL]
ifFalse: [other].
^target == compareTo
)

----------------------------

| semantics |

"Accessing"
semantics = ( ^semantics )
semantics: anObject = ( semantics := anObject )

initialize = (
HandleForArray initialize.
HandleForClass initialize.
ImmutableMessageForHandlesMO initialize.
ImmutableMessageForArrayHandlesMO initialize.
ImmutableMessageForClassHandlesMO initialize.

self semantics:
(EnvironmentMO
operationalSemantics: ImmutableSemanticsForHandlesMO new
message: ImmutableMessageForHandlesMO new
layout: nil
).
)

targetSPECIAL: anObject = (
| object |
(anObject class = self) ifTrue: [^anObject].
object := self basicNew: self semantics.
object targetSPECIAL: anObject.
^object
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
HandleForArray = HandleSupportingPrimitives (

----------------------------

messageMO = ( ^ImmutableMessageForArrayHandlesMO new)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
HandleForClass = HandleSupportingPrimitives (

----------------------------

messageMO = ( ^ImmutableMessageForClassHandlesMO new)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
HandleSupportingPrimitives = Handle (

--------------

initialize = (
| shape |
self semantics:
(EnvironmentMO
operationalSemantics: ImmutableSemanticsForHandlesMO new
message: self messageMO
layout: nil
).
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
ImmutableMessageForArrayHandlesMO = ImmutableMessageForPrimitivesMO (
find: aSymbol since: aClass = (
(ImmutableMessageForArrayHandlesMO writablePrimitives contains: aSymbol)
ifTrue: ['ERROR: Unexpected write to a readonly object!' println. self halt. ^nil]
^(ImmutableMessageForArrayHandlesMO returningPrimitives containsKey: aSymbol)
ifTrue: [super find: (ImmutableMessageForArrayHandlesMO returningPrimitives at: aSymbol) since: aClass]
ifFalse: [super find: aSymbol since: aClass]
)

activate: aSignature withArguments: arguments = (
(ImmutableMessageForArrayHandlesMO primitives contains: aSignature) ifTrue:[
arguments at:3 put: (arguments at: 3) targetSPECIAL.
]
^arguments
)
----------------------------
initialize = (
Primitives := #(#length).
WritablePrimitives := #(#at:put:).

"We must wrap returning primitives so that the returned value is wrapped with a readonly reference"
ReturningPrimitives := Dictionary new.
ReturningPrimitives at: #at: put: #atHandlesSPECIAL:
)

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ImmutableMessageForClassHandlesMO = ImmutableMessageForPrimitivesMO (
find: aSymbol since: aClass = (
(ImmutableMessageForClassHandlesMO writablePrimitives contains: aSymbol)
ifTrue: ['ERROR: Unexpected write to a readonly object!' println. self halt. ^nil]
^(ImmutableMessageForClassHandlesMO returningPrimitives containsKey: aSymbol)
ifTrue: [super find: (ImmutableMessageForClassHandlesMO returningPrimitives at: aSymbol) since: aClass]
ifFalse: [super find: aSymbol since: aClass]
)

activate: aSignature withArguments: arguments = (
(ImmutableMessageForClassHandlesMO primitives contains: aSignature) ifTrue:[
arguments at:3 put: (arguments at: 3) targetSPECIAL.
]
^arguments
)
----------------------------

initialize = (
Primitives := #().
WritablePrimitives := #(#basicNew).

"We must wrap returning primitives so that the returned value is wrapped with a readonly reference"
ReturningPrimitives := Dictionary new.
ReturningPrimitives at: #superclass put: #superclassSPECIAL.
ReturningPrimitives at: #fields put: #fieldsSPECIAL.
ReturningPrimitives at: #methods put: #methodsSPECIAL.
ReturningPrimitives at: #name put: #nameSPECIAL.
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
ImmutableMessageForHandlesMO = MessageLookupMO (
find: aSymbol since: aClass = (
| lookupStart |
lookupStart := (ImmutableMessageForHandlesMO reimplementedPrimitives contains: aSymbol)
ifTrue: [self class]
ifFalse: [self targetSPECIAL class].
^super find: aSymbol since: lookupStart
)

----------------------------
| ReimplementedPrimitives |

initialize = (
ReimplementedPrimitives := #(#= #== #equalsequalsSPECIAL: #equalsSPECIAL:)
)
reimplementedPrimitives = (^ReimplementedPrimitives)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ImmutableMessageForPrimitivesMO = ImmutableMessageForHandlesMO (
----------------------------
| WritablePrimitives ReturningPrimitives Primitives |

writablePrimitives = (^WritablePrimitives)
returningPrimitives = (^ReturningPrimitives)
primitives = (^Primitives)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ImmutableSemanticsForHandlesMO = OperationalSemanticsMO (
read: anIndex = (^(self targetSPECIAL instVarAt: anIndex) readOnly)
write: anIndex value: aValue = (^aValue)
)
2 changes: 1 addition & 1 deletion Smalltalk/Object.som
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Object = nil (
"Debugging"
inspect = primitive
halt = primitive
hasMetaObjectEnvironment = primitive
hasEnvironment = primitive
inMeta = primitive

"Error handling"
Expand Down