Skip to content

Commit 828f90b

Browse files
committed
Wasm: Compute tableEntries in Preprocessor.
`ClassInfo` is now completely immutable.
1 parent 2cbe367 commit 828f90b

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 = {
@@ -183,12 +180,38 @@ object Preprocessor {
183180
}
184181
}
185182

183+
val tableEntries: List[MethodName] = {
184+
val methodsCalledDynamically: List[MethodName] =
185+
if (clazz.hasInstances) methodsCalledDynamically0.toList
186+
else Nil
187+
188+
kind match {
189+
case ClassKind.Class | ClassKind.ModuleClass | ClassKind.HijackedClass =>
190+
val superTableEntries = superClass.fold[List[MethodName]](Nil)(_.tableEntries)
191+
val superTableEntrySet = superTableEntries.toSet
192+
193+
/* When computing the table entries to add for this class, exclude
194+
* methods that are already in the super class' table entries.
195+
*/
196+
val newTableEntries = methodsCalledDynamically
197+
.filter(!superTableEntrySet.contains(_))
198+
.sorted // for stability
199+
200+
superTableEntries ::: newTableEntries
201+
202+
case ClassKind.Interface =>
203+
methodsCalledDynamically.sorted // for stability
204+
205+
case _ =>
206+
Nil
207+
}
208+
}
209+
186210
new ClassInfo(
187211
className,
188212
kind,
189213
clazz.jsClassCaptures,
190214
allFieldDefs,
191-
superClass,
192215
classImplementsAnyInterface,
193216
clazz.hasInstances,
194217
!clazz.hasDirectInstances,
@@ -198,6 +221,7 @@ object Preprocessor {
198221
staticFieldMirrors,
199222
specialInstanceTypes,
200223
resolvedMethodInfos,
224+
tableEntries,
201225
itableIdx
202226
)
203227
}

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, // should be `val` but there is a large Scaladoc for it below
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)