From 1d5c1e527a33b7aa96f32d4197c110518bed17d1 Mon Sep 17 00:00:00 2001 From: Chad Retz Date: Wed, 25 Jul 2018 15:59:27 -0500 Subject: [PATCH] Emit given names in compiled class. Fixes #17 --- .../kotlin/asmble/compile/jvm/ClsContext.kt | 11 +++++- .../src/main/kotlin/asmble/io/BinaryToAst.kt | 3 +- .../kotlin/asmble/compile/jvm/NamesTest.kt | 38 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 compiler/src/test/kotlin/asmble/compile/jvm/NamesTest.kt diff --git a/compiler/src/main/kotlin/asmble/compile/jvm/ClsContext.kt b/compiler/src/main/kotlin/asmble/compile/jvm/ClsContext.kt index 0827825..3eb996c 100644 --- a/compiler/src/main/kotlin/asmble/compile/jvm/ClsContext.kt +++ b/compiler/src/main/kotlin/asmble/compile/jvm/ClsContext.kt @@ -39,6 +39,15 @@ data class ClsContext( val hasTable: Boolean by lazy { mod.tables.isNotEmpty() || mod.imports.any { it.kind is Node.Import.Kind.Table } } + val dedupedFuncNames: Map? by lazy { + val seen = mutableSetOf() + mod.names?.funcNames?.toList()?.sortedBy { it.first }?.map { (index, origName) -> + var name = origName + var nameIndex = 0 + while (!seen.add(name)) name = origName + (nameIndex++) + index to name + }?.toMap() + } fun assertHasMemory() { if (!hasMemory) throw CompileErr.UnknownMemory(0) } @@ -71,7 +80,7 @@ data class ClsContext( fun importGlobalGetterFieldName(index: Int) = "import\$get" + globalName(index) fun importGlobalSetterFieldName(index: Int) = "import\$set" + globalName(index) fun globalName(index: Int) = "\$global$index" - fun funcName(index: Int) = "\$func$index" + fun funcName(index: Int) = dedupedFuncNames?.get(index)?.javaIdent ?: "\$func$index" private fun syntheticFunc( nameSuffix: String, diff --git a/compiler/src/main/kotlin/asmble/io/BinaryToAst.kt b/compiler/src/main/kotlin/asmble/io/BinaryToAst.kt index e926368..6c87536 100644 --- a/compiler/src/main/kotlin/asmble/io/BinaryToAst.kt +++ b/compiler/src/main/kotlin/asmble/io/BinaryToAst.kt @@ -217,7 +217,8 @@ open class BinaryToAst( } // Try to parse the name section val section = toCustomSection(b, afterSectionId).takeIf { section -> - val shouldParseNames = includeNameSection && customSections.isEmpty() && nameSection == null + val shouldParseNames = includeNameSection && customSections.isEmpty() && + nameSection == null && section.name == "name" !shouldParseNames || try { nameSection = toNameSection(ByteReader.InputStream(section.payload.inputStream())) false diff --git a/compiler/src/test/kotlin/asmble/compile/jvm/NamesTest.kt b/compiler/src/test/kotlin/asmble/compile/jvm/NamesTest.kt new file mode 100644 index 0000000..56826d0 --- /dev/null +++ b/compiler/src/test/kotlin/asmble/compile/jvm/NamesTest.kt @@ -0,0 +1,38 @@ +package asmble.compile.jvm + +import asmble.TestBase +import asmble.io.SExprToAst +import asmble.io.StrToSExpr +import asmble.run.jvm.ScriptContext +import org.junit.Test +import java.util.* + +class NamesTest : TestBase() { + @Test + fun testNames() { + // Compile and make sure the names are set right + val (_, mod) = SExprToAst.toModule(StrToSExpr.parseSingleMulti(""" + (module ${'$'}mod_name + (import "foo" "bar" (func ${'$'}import_func (param i32))) + (type ${'$'}some_sig (func (param ${'$'}type_param i32))) + (func ${'$'}some_func + (type ${'$'}some_sig) + (param ${'$'}func_param i32) + (local ${'$'}func_local0 i32) + (local ${'$'}func_local1 f64) + ) + ) + """.trimIndent())) + val ctx = ClsContext( + packageName = "test", + className = "Temp" + UUID.randomUUID().toString().replace("-", ""), + mod = mod, + logger = logger + ) + AstToAsm.fromModule(ctx) + val cls = ScriptContext.SimpleClassLoader(javaClass.classLoader, logger).fromBuiltContext(ctx) + // Make sure the import field and the func are present named + cls.getDeclaredField("\$import_func") + cls.getDeclaredMethod("\$some_func", Integer.TYPE) + } +} \ No newline at end of file