128 lines
3.8 KiB
Kotlin
128 lines
3.8 KiB
Kotlin
/*
|
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
*/
|
|
|
|
package org.jetbrains.kotlin.generators.wasm
|
|
|
|
import org.jetbrains.kotlin.wasm.ir.WasmOp
|
|
import java.io.File
|
|
import java.io.FileWriter
|
|
|
|
fun FileWriter.generateStandardWasmInternalHeader() {
|
|
appendLine(File("license/COPYRIGHT_HEADER.txt").readText())
|
|
appendLine()
|
|
appendLine("package kotlin.wasm.internal")
|
|
appendLine()
|
|
appendLine("//")
|
|
appendLine("// NOTE: THIS FILE IS AUTO-GENERATED by the generators/wasm/WasmIntrinsicGenerator.kt")
|
|
appendLine("//")
|
|
appendLine()
|
|
}
|
|
|
|
fun generateWasmOps(targetDir: File) {
|
|
FileWriter(targetDir.resolve("_WasmOp.kt")).use { writer ->
|
|
writer.generateStandardWasmInternalHeader()
|
|
writer.appendLine(
|
|
"""
|
|
@ExcludedFromCodegen
|
|
@Suppress("unused")
|
|
@Target(AnnotationTarget.FUNCTION)
|
|
@Retention(AnnotationRetention.BINARY)
|
|
internal annotation class WasmOp(val name: String) {
|
|
companion object {
|
|
""".trimIndent()
|
|
)
|
|
WasmOp.values().forEach { op ->
|
|
writer.appendLine(" const val $op = \"$op\"")
|
|
}
|
|
writer.appendLine(
|
|
"""
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
)
|
|
}
|
|
}
|
|
|
|
fun generateWasmArrays(targetDir: File) {
|
|
FileWriter(targetDir.resolve("_WasmArrays.kt")).use { writer ->
|
|
writer.generateStandardWasmInternalHeader()
|
|
|
|
writer.appendLine(wasmArrayForType("Any", true))
|
|
val types = listOf(
|
|
"Byte",
|
|
"Char",
|
|
"Short",
|
|
"Int",
|
|
"Long",
|
|
"Float",
|
|
"Double"
|
|
)
|
|
|
|
types.forEach { primitive ->
|
|
val isPacked = primitive in setOf(
|
|
"Byte",
|
|
"Char",
|
|
"Short",
|
|
)
|
|
val isUnsigned = primitive == "Char"
|
|
|
|
writer.appendLine(
|
|
wasmArrayForType(
|
|
primitive,
|
|
false, isPacked, isUnsigned
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun wasmArrayForType(
|
|
klass: String,
|
|
isNullable: Boolean,
|
|
isPacked: Boolean = false,
|
|
isUnsigned: Boolean = false,
|
|
): String {
|
|
val type = klass + if (isNullable) "?" else ""
|
|
val name = "Wasm${klass}Array"
|
|
val getSuffix = when {
|
|
isPacked && isUnsigned -> "_U"
|
|
isPacked && !isUnsigned -> "_S"
|
|
else -> ""
|
|
}
|
|
return """
|
|
@WasmArrayOf($klass::class, isNullable = $isNullable)
|
|
internal class $name(size: Int) {
|
|
@WasmOp(WasmOp.ARRAY_GET${getSuffix})
|
|
fun get(index: Int): $type =
|
|
implementedAsIntrinsic
|
|
|
|
@WasmOp(WasmOp.ARRAY_SET)
|
|
fun set(index: Int, value: $type): Unit =
|
|
implementedAsIntrinsic
|
|
|
|
@WasmOp(WasmOp.ARRAY_LEN)
|
|
fun len(): Int =
|
|
implementedAsIntrinsic
|
|
}
|
|
|
|
internal inline fun copyWasmArray(source: $name, destination: $name, sourceIndex: Int, destinationIndex: Int, length: Int) {
|
|
wasm_array_copy<$name>(destination, destinationIndex, source, sourceIndex, length)
|
|
}
|
|
|
|
internal inline fun $name.fill(size: Int, init: (Int) -> $type) {
|
|
var i = 0
|
|
while (i < size) {
|
|
set(i, init(i))
|
|
i++
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
}
|
|
|
|
fun main() {
|
|
val targetDir = File("libraries/stdlib/wasm/src/generated")
|
|
generateWasmOps(targetDir)
|
|
generateWasmArrays(targetDir)
|
|
} |