| /* |
| * 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 main() { |
| val targetDir = File("libraries/stdlib/wasm/src/generated/wasm/internal/") |
| generateWasmOps(targetDir) |
| generateWasmArrays(targetDir) |
| } |
| |
| private 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() |
| } |
| |
| private 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() |
| ) |
| } |
| } |
| |
| private 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 |
| ) |
| ) |
| } |
| } |
| } |
| |
| private 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 """ |
| @Suppress("UNUSED_PARAMETER") |
| @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 |
| } |
| |
| @Suppress("NOTHING_TO_INLINE") |
| 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() |
| } |