Skip to content

Commit 2a55ade

Browse files
alex28shSpace Team
authored andcommitted
[Wasm] fix for classnames
1 parent 798893d commit 2a55ade

File tree

6 files changed

+60
-47
lines changed

6 files changed

+60
-47
lines changed

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/ConstantData.kt

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ private fun addressToString(address: Int): String =
2727
class ConstantDataCharField(val value: WasmSymbol<Char>) : ConstantDataElement() {
2828
constructor(value: Char) : this(WasmSymbol(value))
2929

30-
override fun toBytes(): ByteArray = ByteArray(2).apply { value.owner.toLittleEndianBytes(this, false, 0) }
30+
override fun toBytes(): ByteArray = value.owner.toLittleEndianBytes(false)
3131

3232
override fun dump(indent: String, startAddress: Int): String {
3333
return "${addressToString(startAddress)}: $indent i32 : ${value.owner} ;;\n"
@@ -39,7 +39,7 @@ class ConstantDataCharField(val value: WasmSymbol<Char>) : ConstantDataElement()
3939
class ConstantDataIntField(val value: WasmSymbol<Int>) : ConstantDataElement() {
4040
constructor(value: Int) : this(WasmSymbol(value))
4141

42-
override fun toBytes(): ByteArray = ByteArray(4).apply { value.owner.toLittleEndianBytes(this, 0) }
42+
override fun toBytes(): ByteArray = value.owner.toLittleEndianBytes()
4343

4444
override fun dump(indent: String, startAddress: Int): String {
4545
return "${addressToString(startAddress)}: $indent i32 : ${value.owner} ;;\n"
@@ -67,11 +67,7 @@ class ConstantDataIntegerArray(val value: List<Long>, val integerSize: Int) : Co
6767

6868
class ConstantDataIntArray(val value: List<WasmSymbol<Int>>) : ConstantDataElement() {
6969
override fun toBytes(): ByteArray {
70-
return ByteArray(value.size * 4).apply {
71-
for (index in value.indices) {
72-
value[index].owner.toLittleEndianBytes(this, index * 4)
73-
}
74-
}
70+
return value.fold(byteArrayOf()) { acc, el -> acc + el.owner.toLittleEndianBytes() }
7571
}
7672

7773
override fun dump(indent: String, startAddress: Int): String {
@@ -82,16 +78,13 @@ class ConstantDataIntArray(val value: List<WasmSymbol<Int>>) : ConstantDataEleme
8278
override val sizeInBytes: Int = value.size * INT_SIZE_BYTES
8379
}
8480

85-
class ConstantDataCharArray(val value: List<WasmSymbol<Char>>) : ConstantDataElement() {
86-
constructor(value: CharArray) : this(value.map { WasmSymbol(it) })
87-
88-
private val isLatin: Boolean
89-
get() = value.all { it.owner.code in 0..255 }
81+
class ConstantDataCharArray(val value: List<WasmSymbol<Char>>, val fitsOneByte: Int) : ConstantDataElement() {
82+
constructor(value: CharArray, fitsOneByte: Int) : this(value.map { WasmSymbol(it) }, fitsOneByte)
9083

9184
override fun toBytes(): ByteArray {
92-
return ByteArray(sizeInBytes).apply {
93-
value.forEachIndexed { index, symbol -> symbol.owner.toLittleEndianBytes(this, isLatin, index * 2) }
94-
}
85+
return value
86+
.map { it.owner.toLittleEndianBytes(fitsOneByte != 0) }
87+
.fold(byteArrayOf(), ByteArray::plus)
9588
}
9689

9790
override fun dump(indent: String, startAddress: Int): String {
@@ -100,18 +93,12 @@ class ConstantDataCharArray(val value: List<WasmSymbol<Char>>) : ConstantDataEle
10093
}
10194

10295
override val sizeInBytes: Int = value.size *
103-
if (isLatin) BYTE_SIZE_BYTES else CHAR_SIZE_BYTES
96+
if (fitsOneByte != 0) BYTE_SIZE_BYTES else CHAR_SIZE_BYTES
10497
}
10598

10699
class ConstantDataStruct(val elements: List<ConstantDataElement>) : ConstantDataElement() {
107100
override fun toBytes(): ByteArray {
108-
return buildList {
109-
elements.forEach {
110-
for (byte in it.toBytes()) {
111-
add(byte)
112-
}
113-
}
114-
}.toByteArray()
101+
return elements.fold(byteArrayOf()) { acc, el -> acc + el.toBytes() }
115102
}
116103

117104
override fun dump(indent: String, startAddress: Int): String {
@@ -126,7 +113,7 @@ class ConstantDataStruct(val elements: List<ConstantDataElement>) : ConstantData
126113
return res
127114
}
128115

129-
override val sizeInBytes: Int = elements.sumOf { it.sizeInBytes }
116+
override val sizeInBytes: Int = elements.map { it.sizeInBytes }.sum()
130117
}
131118

132119
fun Long.toLittleEndianBytesTo(to: ByteArray, offset: Int, size: Int) {
@@ -135,16 +122,16 @@ fun Long.toLittleEndianBytesTo(to: ByteArray, offset: Int, size: Int) {
135122
}
136123
}
137124

138-
fun Int.toLittleEndianBytes(to: ByteArray, offset: Int) {
139-
to[offset] = this.toByte()
140-
to[offset + 1] = (this ushr 8).toByte()
141-
to[offset + 2] = (this ushr 16).toByte()
142-
to[offset + 3] = (this ushr 24).toByte()
125+
126+
fun Int.toLittleEndianBytes(): ByteArray {
127+
return ByteArray(4) {
128+
(this ushr (it * 8)).toByte()
129+
}
143130
}
144131

145-
fun Char.toLittleEndianBytes(to: ByteArray, isLatin: Boolean, offset: Int) {
146-
to[offset] = (this.code and 0xFF).toByte()
147-
if (!isLatin) {
148-
to[offset + 1] = (this.code ushr Byte.SIZE_BITS).toByte()
132+
fun Char.toLittleEndianBytes(fitsOneByte: Boolean): ByteArray {
133+
if (fitsOneByte) {
134+
return byteArrayOf((this.code and 0xFF).toByte())
149135
}
136+
return byteArrayOf((this.code and 0xFF).toByte(), (this.code ushr Byte.SIZE_BITS).toByte())
150137
}

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
3131

3232
private const val TYPE_INFO_FLAG_ANONYMOUS_CLASS = 1
3333
private const val TYPE_INFO_FLAG_LOCAL_CLASS = 2
34+
private const val TYPE_INFO_FLAG_FITS_ONE_BIT_QUALIFIER = 4
35+
private const val TYPE_INFO_FLAG_FITS_ONE_BIT_SIMPLE_NAME = 8
3436

3537
class DeclarationGenerator(
3638
private val backendContext: WasmBackendContext,
@@ -397,7 +399,9 @@ class DeclarationGenerator(
397399

398400
val isAnonymousFlag = if (klass.isAnonymousObject) TYPE_INFO_FLAG_ANONYMOUS_CLASS else 0
399401
val isLocalFlag = if (klass.isOriginallyLocalClass) TYPE_INFO_FLAG_LOCAL_CLASS else 0
400-
buildConstI32(isAnonymousFlag or isLocalFlag, location)
402+
val fitsOneByteQualifier = if (qualifier.all { it.code in 0..255 }) TYPE_INFO_FLAG_FITS_ONE_BIT_QUALIFIER else 0
403+
val fitsOneByteSimpleName = if (simpleName.all { it.code in 0..255 }) TYPE_INFO_FLAG_FITS_ONE_BIT_SIMPLE_NAME else 0
404+
buildConstI32(isAnonymousFlag or isLocalFlag or fitsOneByteQualifier or fitsOneByteSimpleName, location)
401405

402406
buildStructNew(wasmFileCodegenContext.rttiType, location)
403407
}

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,9 @@ class WasmCompiledModuleFragment(
553553
currentStringId = stringAddressAndId.size
554554
stringAddressAndId[string] = currentStringAddress to currentStringId
555555

556-
val constData = ConstantDataCharArray(string.toCharArray())
556+
val fitsOneByte = if (string.all { it.code in 0..255 }) 1 else 0
557+
558+
val constData = ConstantDataCharArray(string.toCharArray(), fitsOneByte)
557559
stringDataSectionBytes += constData.toBytes().toList()
558560
stringDataSectionStart += constData.sizeInBytes
559561
} else {

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/serialization/WasmDeserializer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@ class WasmDeserializer(inputStream: InputStream, private val skipLocalNames: Boo
489489

490490
private fun deserializeConstantDataCharArray(): ConstantDataCharArray {
491491
val value = deserializeList { deserializeSymbol { Char(deserializeInt()) } }
492-
return ConstantDataCharArray(value)
492+
val fitsOneByte = deserializeInt()
493+
return ConstantDataCharArray(value, fitsOneByte)
493494
}
494495

495496
private fun deserializeConstantDataCharField(): ConstantDataCharField {

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/serialization/WasmSerializer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ class WasmSerializer(outputStream: OutputStream) {
515515

516516
private fun serializeConstantDataCharArray(constantDataCharArray: ConstantDataCharArray) {
517517
serializeList(constantDataCharArray.value) { serializeWasmSymbolReadOnly(it) { b.writeUInt32(it.code.toUInt()) } }
518+
serializeInt(constantDataCharArray.fitsOneByte)
518519
}
519520

520521
private fun serializeConstantDataCharField(constantDataCharField: ConstantDataCharField) {

libraries/stdlib/wasm/internal/kotlin/wasm/internal/TypeInfo.kt

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ internal class TypeInfoData(val typeId: Long, val packageName: String, val typeN
1111

1212
private const val TYPE_INFO_FLAG_ANONYMOUS_CLASS = 1
1313
private const val TYPE_INFO_FLAG_LOCAL_CLASS = 2
14+
private const val TYPE_INFO_FLAG_FITS_ONE_BIT_QUALIFIER = 4
15+
private const val TYPE_INFO_FLAG_FITS_ONE_BIT_SIMPLE_NAME = 8
1416

1517
@Suppress("UNUSED_PARAMETER")
1618
@WasmArrayOf(Long::class, isNullable = false, isMutable = false)
@@ -56,17 +58,33 @@ internal fun getQualifiedName(rtti: kotlin.wasm.internal.reftypes.structref): St
5658
return if (packageName.isEmpty()) typeName else "$packageName.$typeName"
5759
}
5860

59-
internal fun getPackageName(rtti: kotlin.wasm.internal.reftypes.structref): String = stringLiteralUTF16(
60-
startAddress = wasmGetRttiIntField(2, rtti),
61-
length = wasmGetRttiIntField(3, rtti),
62-
poolId = wasmGetRttiIntField(4, rtti),
63-
)
64-
65-
internal fun getSimpleName(rtti: kotlin.wasm.internal.reftypes.structref): String = stringLiteralUTF16(
66-
startAddress = wasmGetRttiIntField(5, rtti),
67-
length = wasmGetRttiIntField(6, rtti),
68-
poolId = wasmGetRttiIntField(7, rtti),
69-
)
61+
internal fun getPackageName(rtti: kotlin.wasm.internal.reftypes.structref): String =
62+
if ((wasmGetRttiIntField(9, rtti) and TYPE_INFO_FLAG_FITS_ONE_BIT_QUALIFIER) != 0)
63+
stringLiteralLatin(
64+
startAddress = wasmGetRttiIntField(2, rtti),
65+
length = wasmGetRttiIntField(3, rtti),
66+
poolId = wasmGetRttiIntField(4, rtti),
67+
)
68+
else
69+
stringLiteralUTF16(
70+
startAddress = wasmGetRttiIntField(2, rtti),
71+
length = wasmGetRttiIntField(3, rtti),
72+
poolId = wasmGetRttiIntField(4, rtti),
73+
)
74+
75+
internal fun getSimpleName(rtti: kotlin.wasm.internal.reftypes.structref): String =
76+
if ((wasmGetRttiIntField(9, rtti) and TYPE_INFO_FLAG_FITS_ONE_BIT_SIMPLE_NAME) != 0)
77+
stringLiteralLatin(
78+
startAddress = wasmGetRttiIntField(5, rtti),
79+
length = wasmGetRttiIntField(6, rtti),
80+
poolId = wasmGetRttiIntField(7, rtti),
81+
)
82+
else
83+
stringLiteralUTF16(
84+
startAddress = wasmGetRttiIntField(5, rtti),
85+
length = wasmGetRttiIntField(6, rtti),
86+
poolId = wasmGetRttiIntField(7, rtti),
87+
)
7088

7189
internal fun getTypeId(rtti: kotlin.wasm.internal.reftypes.structref): Long =
7290
wasmGetRttiLongField(8, rtti)

0 commit comments

Comments
 (0)