Emit given names in compiled class. Fixes #17

This commit is contained in:
Chad Retz 2018-07-25 15:59:27 -05:00
parent 1430bf48a6
commit 1d5c1e527a
3 changed files with 50 additions and 2 deletions

View File

@ -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<Int, String>? by lazy {
val seen = mutableSetOf<String>()
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,

View File

@ -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

View File

@ -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)
}
}