1 prototypes define: #RoleEntry &parents: {Cloneable}
2 &slots: {#selector. #rolePositions. #methodDefinition}.
3 "An object representing an entry in the object Map table for a method dispatch
6 r1@(RoleEntry traits) = r2@(RoleEntry traits)
8 r1 selector == r2 selector
9 /\ [r1 rolePositions = r2 rolePositions]
10 /\ [r1 methodDefinition = r2 methodDefinition]
13 r@(RoleEntry traits) hash
15 (r selector hash bitXor: r rolePositions hash)
16 bitXor: r methodDefinition hash
19 r@(RoleEntry traits) appliesToPosition: dispatchIndex
21 (r rolePositions >> dispatchIndex bitAnd: 1) = 1
24 prototypes define: #EmbeddedRoleEntry &parents: {RoleEntry}
25 &slots: {#nextRoleIndex. #table}.
26 "A RoleEntry subtype for describing the dispatch record installation as-is
27 within the table, so that the table can be traversed."
29 r@(EmbeddedRoleEntry traits) nextRole
31 r nextRoleIndex ifNotNilDo: [| :index | r table at: index]
34 m@(Map traits) roleInTableAt: index
35 "Takes a raw index into the RoleTable array and answers a RoleEntry object with
36 that as starting index, or Nil if there is none."
38 (m roleTable at: index) ifNotNilDo:
42 #(selector rolePositions methodDefinition nextRoleIndex)
44 m roleTable at: index + 1.
45 m roleTable at: index + 2.
46 m roleTable at: index + 3}]
49 Map traits define: #RoleReadStream &parents: {ReadStream}
50 &slots: {#map. #index -> 0 "The raw index into the role table."}.
51 "An in-order traversal stream over the role-table in a Map, returning
52 EmbeddedRoleEntry objects."
54 m@(Map RoleReadStream traits) on: map [m map: map. m].
56 m@(Map traits) roleReadStream [m RoleReadStream newOn: m].
58 obj@(Root traits) roleReader [obj _map roleReadStream].
60 m@(Map RoleReadStream traits) reset [m index: 0. m].
62 m@(Map RoleReadStream traits) elementType [RoleEntry].
64 m@(Map RoleReadStream traits) isAtEnd
65 [m index > m map roleTable indexLast].
67 m@(Map RoleReadStream traits) next
68 "TODO: prevent this from returning Nil when it reaches the end... raise Exhaustion?"
70 [m isAtEnd] whileFalse:
71 [result: (m map roleInTableAt: m index).
73 result ifNotNil: [^ result]]
77 "Answers all the roles applying to the object."
78 [((x roleReader select: [| :role | role isNotNil]) >> {} writer) contents].
80 x@(Root traits) rolesAt: dispatchIndex
81 "Answer the roles applying to the object at the given argument dispatch index."
83 ((x roleReader select:
84 [| :role | role isNotNil /\ [role appliesToPosition: dispatchIndex]])
85 >> {} writer) contents
88 x@(Root traits) roleIndices
89 "Answer the position indices that the object has roles for."
91 rolePositions: (x roleReader inject: 0 into:
92 [| :positions :role | positions bitOr:
93 (role ifNil: [0] ifNotNil: [role rolePositions])]) last.
95 (rolePositions as: BitArray) doWithIndex:
96 [| :isRole :index | isRole ifTrue: [result nextPut: index]]] writingAs: {}
99 x@(Root traits) rolesNamed: selector
100 "Answer the roles applying to the object for the given selector, in any
101 position. This will not return duplicates."
103 ((x roleReader select:
104 [| :role | role isNotNil /\ [role selector == selector]])
105 >> IdentitySet new writer) contents
108 x@(Root traits) rolesNamed: selector at: dispatchIndex
109 "Answer the roles applying to the object for the given selector, in the given
110 position. This will not return duplicates."
112 ((x roleReader select:
113 [| :role | role isNotNil /\ [role selector == selector] /\
114 [role appliesToPosition: dispatchIndex]])
115 >> IdentitySet new writer) contents
118 x@(Root traits) methods
119 [x roles collect: [| :r | r methodDefinition method]].
121 x@(Root traits) accessorMethods
123 selectors: (x slotNames collect: [| :s | x accessorNameFor: s]).
124 (((x roleReader select: [| :r | selectors includes: r selector])
125 collect: [| :r | r methodDefinition method])
126 >> IdentitySet new writer) contents
129 x@(Root traits) mutatorMethods
131 selectors: (x slotNames collect: [| :s | x mutatorNameFor: s]).
132 (((x roleReader select: [| :r | selectors includes: r selector])
133 collect: [| :r | r methodDefinition method])
134 >> IdentitySet new writer) contents
137 x@(Root traits) methodsNamed: selector
139 (x rolesNamed: selector) select:
140 [| :r | r selector = selector] collect: [| :r | r methodDefinition method]
143 x@(Root traits) hasMethodNamed: selector
145 x roleReader anySatisfy: [| :role | role selector == selector]
148 x@(Root traits) methodsNamed: selector at: dispatchIndex
150 (x rolesNamed: selector at: dispatchIndex) select:
151 [| :r | r selector = selector] collect: [| :r | r methodDefinition method]
154 x@(Root traits) hasMethodNamed: selector at: dispatchIndex
156 x roleReader anySatisfy: [| :role | role selector == selector
157 /\ [role appliesToPosition: dispatchIndex]]
160 x@(Root traits) methodsAt: dispatchIndex
162 (x rolesAt: dispatchIndex)
163 collect: [| :r | r methodDefinition method]
166 x@(Root traits) methodsSending: selector
168 ((x roleReader select:
169 [| :r | r isNotNil /\
170 [r methodDefinition method allSelectorsSent includes: selector]])
171 >> [| :r | r methodDefinition method]
172 >> IdentitySet new writer) contents
175 x@(Root traits) methodsSendingMacro: selector
179 [| :r m | m: (r ifNotNil: [r methodDefinition method]).
180 (m isSameAs: CompiledMethod) ifTrue:
181 [m sourceTree ifNotNilDo:
183 (src allMacroSelectorsSent includes: selector)
184 ifTrue: [result nextPut: m]]]]]
185 writingAs: IdentitySet