Skip to content

Commit 427dd73

Browse files
committed
Wasm: Compute tableEntries in Preprocessor.
`ClassInfo` is now completely immutable.
1 parent 157ed5b commit 427dd73

File tree

2 files changed

+31
-46
lines changed

2 files changed

+31
-46
lines changed

linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ object Preprocessor {
4444
clazz,
4545
staticFieldMirrors.getOrElse(clazz.className, Map.empty),
4646
specialInstanceTypes.getOrElse(clazz.className, 0),
47+
abstractMethodCalls.getOrElse(clazz.className, Set.empty),
4748
itableBucketAssignments.getOrElse(clazz.className, -1),
4849
clazz.superClass.map(sup => classInfosBuilder(sup.name))
4950
)
@@ -61,11 +62,6 @@ object Preprocessor {
6162
// sort for stability
6263
val reflectiveProxyIDs = definedReflectiveProxyNames.toList.sorted.zipWithIndex.toMap
6364

64-
for (clazz <- classes) {
65-
classInfos(clazz.className).buildMethodTable(
66-
abstractMethodCalls.getOrElse(clazz.className, Set.empty))
67-
}
68-
6965
new WasmContext(classInfos, reflectiveProxyIDs, itableBucketCount)
7066
}
7167

@@ -118,6 +114,7 @@ object Preprocessor {
118114
clazz: LinkedClass,
119115
staticFieldMirrors: Map[FieldName, List[String]],
120116
specialInstanceTypes: Int,
117+
methodsCalledDynamically0: Set[MethodName],
121118
itableIdx: Int,
122119
superClass: Option[ClassInfo]
123120
): ClassInfo = {
@@ -187,12 +184,38 @@ object Preprocessor {
187184
}
188185
}
189186

187+
val tableEntries: List[MethodName] = {
188+
val methodsCalledDynamically: List[MethodName] =
189+
if (clazz.hasInstances) methodsCalledDynamically0.toList
190+
else Nil
191+
192+
kind match {
193+
case ClassKind.Class | ClassKind.ModuleClass | ClassKind.HijackedClass =>
194+
val superTableEntries = superClass.fold[List[MethodName]](Nil)(_.tableEntries)
195+
val superTableEntrySet = superTableEntries.toSet
196+
197+
/* When computing the table entries to add for this class, exclude
198+
* methods that are already in the super class' table entries.
199+
*/
200+
val newTableEntries = methodsCalledDynamically
201+
.filter(!superTableEntrySet.contains(_))
202+
.sorted // for stability
203+
204+
superTableEntries ::: newTableEntries
205+
206+
case ClassKind.Interface =>
207+
methodsCalledDynamically.sorted // for stability
208+
209+
case _ =>
210+
Nil
211+
}
212+
}
213+
190214
new ClassInfo(
191215
className,
192216
kind,
193217
clazz.jsClassCaptures,
194218
allFieldDefs,
195-
superClass,
196219
classImplementsAnyInterface,
197220
clazz.hasInstances,
198221
!clazz.hasDirectInstances,
@@ -202,6 +225,7 @@ object Preprocessor {
202225
staticFieldMirrors,
203226
specialInstanceTypes,
204227
resolvedMethodInfos,
228+
tableEntries,
205229
itableIdx
206230
)
207231
}

linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ object WasmContext {
169169
val kind: ClassKind,
170170
val jsClassCaptures: Option[List[ParamDef]],
171171
val allFieldDefs: List[FieldDef],
172-
superClass: Option[ClassInfo],
173172
val classImplementsAnyInterface: Boolean,
174173
val hasInstances: Boolean,
175174
val isAbstract: Boolean,
@@ -179,14 +178,12 @@ object WasmContext {
179178
val staticFieldMirrors: Map[FieldName, List[String]],
180179
_specialInstanceTypes: Int,
181180
val resolvedMethodInfos: Map[MethodName, ConcreteMethodInfo],
181+
val tableEntries: List[MethodName],
182182
_itableIdx: Int
183183
) {
184184
override def toString(): String =
185185
s"ClassInfo(${name.nameString})"
186186

187-
/** For a class or interface, its table entries in definition order. */
188-
private var _tableEntries: List[MethodName] = null
189-
190187
/** Returns the index of this interface's itable in the classes' interface tables.
191188
*
192189
* Only interfaces that have instances get an itable index.
@@ -246,42 +243,6 @@ object WasmContext {
246243

247244
def isInterface: Boolean =
248245
kind == ClassKind.Interface
249-
250-
def buildMethodTable(methodsCalledDynamically0: Set[MethodName]): Unit = {
251-
if (_tableEntries != null)
252-
throw new IllegalStateException(s"Duplicate call to buildMethodTable() for $name")
253-
254-
val methodsCalledDynamically: List[MethodName] =
255-
if (hasInstances) methodsCalledDynamically0.toList
256-
else Nil
257-
258-
kind match {
259-
case ClassKind.Class | ClassKind.ModuleClass | ClassKind.HijackedClass =>
260-
val superTableEntries = superClass.fold[List[MethodName]](Nil)(_.tableEntries)
261-
val superTableEntrySet = superTableEntries.toSet
262-
263-
/* When computing the table entries to add for this class, exclude
264-
* methods that are already in the super class' table entries.
265-
*/
266-
val newTableEntries = methodsCalledDynamically
267-
.filter(!superTableEntrySet.contains(_))
268-
.sorted // for stability
269-
270-
_tableEntries = superTableEntries ::: newTableEntries
271-
272-
case ClassKind.Interface =>
273-
_tableEntries = methodsCalledDynamically.sorted // for stability
274-
275-
case _ =>
276-
_tableEntries = Nil
277-
}
278-
}
279-
280-
def tableEntries: List[MethodName] = {
281-
if (_tableEntries == null)
282-
throw new IllegalStateException(s"Table not yet built for $name")
283-
_tableEntries
284-
}
285246
}
286247

287248
final class ConcreteMethodInfo(val ownerClass: ClassName, val methodName: MethodName) {

0 commit comments

Comments
 (0)