Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit76fef2e

Browse files
authored
Merge pull request#5038 from tanishiking/struct-itables
Wasm: Make itables immutable struct
2 parents4c9494e +614e228 commit76fef2e

File tree

5 files changed

+72
-71
lines changed

5 files changed

+72
-71
lines changed

‎linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ class ClassEmitter(coreSpec: CoreSpec) {
135135
}
136136
}
137137

138+
/** Generate common itable global for all array classes.*/
139+
defgenGlobalArrayClassItable()(implicitctx:WasmContext):Unit= {
140+
genGlobalClassItable(
141+
genGlobalID.arrayClassITable, ctx.getClassInfo(ObjectClass),
142+
List(SerializableClass,CloneableClass),
143+
OriginalName(genGlobalID.arrayClassITable.toString())
144+
)
145+
}
146+
138147
privatedefgenIsJSClassInstanceFunction(clazz:LinkedClass)(
139148
implicitctx:WasmContext):Option[wanme.FunctionID]= {
140149
implicitvalnoPos:Position=Position.NoPosition
@@ -489,8 +498,10 @@ class ClassEmitter(coreSpec: CoreSpec) {
489498
fb+= wa.BrOnNull(testFail)
490499

491500
fb+= wa.LocalGet(itables)
492-
fb+= wa.I32Const(classInfo.itableIdx)
493-
fb+= wa.ArrayGet(genTypeID.itables)
501+
fb+= wa.StructGet(
502+
genTypeID.itables,
503+
genFieldID.itablesStruct.itableSlot(classInfo.itableIdx)
504+
)
494505
fb+= wa.RefTest(watpe.RefType(genTypeID.forITable(className)))
495506
fb+= wa.Return
496507
}// test fail
@@ -785,24 +796,48 @@ class ClassEmitter(coreSpec: CoreSpec) {
785796
*/
786797
privatedefgenGlobalClassItable(clazz:LinkedClass)(implicitctx:WasmContext):Unit= {
787798
valclassName= clazz.className
788-
789-
if (ctx.getClassInfo(className).classImplementsAnyInterface) {
790-
valglobalID= genGlobalID.forITable(className)
791-
valitablesInit=List(
792-
wa.I32Const(ctx.itablesLength),
793-
wa.ArrayNewDefault(genTypeID.itables)
794-
)
795-
valglobal= wamod.Global(
796-
globalID,
797-
makeDebugName(ns.ITable, className),
798-
isMutable=false,
799-
watpe.RefType(genTypeID.itables),
800-
wa.Expr(itablesInit)
799+
valclassInfo= ctx.getClassInfo(className)
800+
if (classInfo.classImplementsAnyInterface) {
801+
genGlobalClassItable(
802+
genGlobalID.forITable(className),
803+
classInfo,
804+
clazz.ancestors,
805+
makeDebugName(ns.ITable, classInfo.name)
801806
)
802-
ctx.addGlobal(global)
803807
}
804808
}
805809

810+
privatedefgenGlobalClassItable(classITableGlobalID: wanme.GlobalID,
811+
classInfoForResolving:WasmContext.ClassInfo,ancestors:List[ClassName],
812+
originalName:OriginalName)(
813+
implicitctx:WasmContext):Unit= {
814+
valitablesInit=Array.fill[List[wa.Instr]](ctx.itablesLength) {
815+
List(wa.RefNull(watpe.HeapType.Struct))
816+
}
817+
valresolvedMethodInfos= classInfoForResolving.resolvedMethodInfos
818+
819+
for {
820+
ancestor<- ancestors
821+
// Use getClassInfoOption in case the reachability analysis got rid of those interfaces
822+
interfaceInfo<- ctx.getClassInfoOption(ancestor)
823+
if interfaceInfo.isInterface
824+
} {
825+
valinit= interfaceInfo.tableEntries.map { method=>
826+
wa.RefFunc(resolvedMethodInfos(method).tableEntryID)
827+
}:+ wa.StructNew(genTypeID.forITable(ancestor))
828+
itablesInit(interfaceInfo.itableIdx)= init
829+
}
830+
831+
valglobal= wamod.Global(
832+
classITableGlobalID,
833+
originalName,
834+
isMutable=false,
835+
watpe.RefType(genTypeID.itables),
836+
wa.Expr(itablesInit.flatten.toList:+ wa.StructNew(genTypeID.itables))
837+
)
838+
ctx.addGlobal(global)
839+
}
840+
806841
privatedefgenInterface(clazz:LinkedClass)(implicitctx:WasmContext):Unit= {
807842
assert(clazz.kind==ClassKind.Interface)
808843
// gen itable type

‎linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ final class CoreWasmLib(coreSpec: CoreSpec) {
120120
genArrayClassTypes()
121121

122122
genBoxedZeroGlobals()
123-
genArrayClassGlobals()
124123
}
125124

126125
// --- Type definitions ---
@@ -161,10 +160,21 @@ final class CoreWasmLib(coreSpec: CoreSpec) {
161160
genTypeID.typeDataArray,
162161
ArrayType(FieldType(RefType(genTypeID.typeData), isMutable=false))
163162
)
163+
164164
genCoreType(
165165
genTypeID.itables,
166-
ArrayType(FieldType(RefType.nullable(HeapType.Struct), isMutable=true))
166+
StructType(
167+
(0 until ctx.itablesLength).map { i=>
168+
StructField(
169+
genFieldID.itablesStruct.itableSlot(i),
170+
OriginalName.NoOriginalName,
171+
RefType.nullable(HeapType.Struct),
172+
isMutable=false
173+
)
174+
}.toList
175+
)
167176
)
177+
168178
genCoreType(
169179
genTypeID.reflectiveProxies,
170180
ArrayType(FieldType(RefType(genTypeID.reflectiveProxy), isMutable=false))
@@ -592,23 +602,6 @@ final class CoreWasmLib(coreSpec: CoreSpec) {
592602
}
593603
}
594604

595-
privatedefgenArrayClassGlobals()(implicitctx:WasmContext):Unit= {
596-
// Common itable global for all array classes
597-
valitablesInit=List(
598-
I32Const(ctx.itablesLength),
599-
ArrayNewDefault(genTypeID.itables)
600-
)
601-
ctx.addGlobal(
602-
Global(
603-
genGlobalID.arrayClassITable,
604-
OriginalName(genGlobalID.arrayClassITable.toString()),
605-
isMutable=false,
606-
RefType(genTypeID.itables),
607-
init=Expr(itablesInit)
608-
)
609-
)
610-
}
611-
612605
// --- Function definitions ---
613606

614607
/** Generates all the helper function definitions of the core Wasm lib.*/

‎linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ final class Emitter(config: Emitter.Config) {
8787
genExternalModuleImports(module)
8888
sortedClasses.foreach(classEmitter.genClassDef(_))
8989
topLevelExports.foreach(classEmitter.genTopLevelExport(_))
90+
classEmitter.genGlobalArrayClassItable()
9091
coreLib.genPostClasses()
9192

9293
genStartFunction(sortedClasses, moduleInitializers, topLevelExports)
@@ -131,40 +132,6 @@ final class Emitter(config: Emitter.Config) {
131132
valfb=
132133
newFunctionBuilder(ctx.moduleBuilder, genFunctionID.start,OriginalName("start"), pos)
133134

134-
// Initialize itables
135-
136-
defgenInitClassITable(classITableGlobalID: wanme.GlobalID,
137-
classInfoForResolving:WasmContext.ClassInfo,ancestors:List[ClassName]):Unit= {
138-
valresolvedMethodInfos= classInfoForResolving.resolvedMethodInfos
139-
140-
for {
141-
ancestor<- ancestors
142-
// Use getClassInfoOption in case the reachability analysis got rid of those interfaces
143-
interfaceInfo<- ctx.getClassInfoOption(ancestor)
144-
if interfaceInfo.isInterface
145-
} {
146-
fb+= wa.GlobalGet(classITableGlobalID)
147-
fb+= wa.I32Const(interfaceInfo.itableIdx)
148-
149-
for (method<- interfaceInfo.tableEntries)
150-
fb+= ctx.refFuncWithDeclaration(resolvedMethodInfos(method).tableEntryID)
151-
fb+= wa.StructNew(genTypeID.forITable(ancestor))
152-
fb+= wa.ArraySet(genTypeID.itables)
153-
}
154-
}
155-
156-
// For all concrete, normal classes
157-
for (clazz<- sortedClassesif clazz.kind.isClass&& clazz.hasDirectInstances) {
158-
valclassName= clazz.className
159-
valclassInfo= ctx.getClassInfo(className)
160-
if (classInfo.classImplementsAnyInterface)
161-
genInitClassITable(genGlobalID.forITable(className), classInfo, clazz.ancestors)
162-
}
163-
164-
// For array classes
165-
genInitClassITable(genGlobalID.arrayClassITable, ctx.getClassInfo(ObjectClass),
166-
List(SerializableClass,CloneableClass))
167-
168135
// Initialize the JS private field symbols
169136

170137
for (clazz<- sortedClassesif clazz.kind.isJSClass) {

‎linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,8 +1151,10 @@ private class FunctionEmitter private (
11511151
defgenITableDispatch():Unit= {
11521152
fb+= wa.LocalGet(receiverLocalForDispatch)
11531153
fb+= wa.StructGet(genTypeID.ObjectStruct, genFieldID.objStruct.itables)
1154-
fb+= wa.I32Const(receiverClassInfo.itableIdx)
1155-
fb+= wa.ArrayGet(genTypeID.itables)
1154+
fb+= wa.StructGet(
1155+
genTypeID.itables,
1156+
genFieldID.itablesStruct.itableSlot(receiverClassInfo.itableIdx)
1157+
)
11561158
fb+= wa.RefCast(watpe.RefType(genTypeID.forITable(receiverClassInfo.name)))
11571159
fb+= wa.StructGet(
11581160
genTypeID.forITable(receiverClassInfo.name),

‎linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/VarGen.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ object VarGen {
294294
caseobjectarrayUnderlyingextendsFieldID
295295
}
296296

297+
objectitablesStruct {
298+
finalcaseclassitableSlot(i:Int)extendsFieldID
299+
}
300+
297301
objectreflectiveProxy {
298302
caseobjectmethodIDextendsFieldID
299303
caseobjectfuncRefextendsFieldID

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp