Skip to content

Commit

Permalink
feat(api): add Descriptors to downcall classes
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Jan 20, 2025
1 parent ad9b23c commit d78146e
Show file tree
Hide file tree
Showing 741 changed files with 37,030 additions and 20,737 deletions.
16 changes: 7 additions & 9 deletions generators/glfw/src/main/kotlin/overrungl/glfw/GLFWGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,11 @@ fun main() {
"glfwTerminate"(void, entrypoint = "glfwTerminate")
"glfwInitHint"(void, int("hint"), int("value"), entrypoint = "glfwInitHint")
+"glfwInitAllocator"(void, const_GLFWallocator_ptr("allocator"), entrypoint = "glfwInitAllocator").overload()
"glfwInitVulkanLoader"(
void,
(address c "PFN_vkGetInstanceProcAddr")("loader"),
entrypoint = "glfwInitVulkanLoader"
)
+"glfwGetVersion"(
void,
int_ptr("major").ref(),
Expand Down Expand Up @@ -1046,21 +1051,12 @@ fun main() {
entrypoint = "glfwGetRequiredInstanceExtensions"
)

//endregion
}

StaticDowncall(glfwPackage, "GLFWVulkan", symbolLookup = glfwLookup) {
val VkInstance = address c "VkInstance"
val VkPhysicalDevice = address c "VkPhysicalDevice"
val const_VkAllocationCallbacks_ptr = address c "const VkAllocationCallbacks*"
val VkSurfaceKHR_ptr = address c "VkSurfaceKHR*"
val VkResult = int c "VkResult"

"glfwInitVulkanLoader"(
void,
(address c "PFN_vkGetInstanceProcAddr")("loader"),
entrypoint = "glfwInitVulkanLoader"
)
+"glfwGetInstanceProcAddress"(
address c "GLFWvkproc",
VkInstance("instance"),
Expand All @@ -1083,6 +1079,8 @@ fun main() {
VkSurfaceKHR_ptr("surface").ref(),
entrypoint = "glfwCreateWindowSurface"
)

//endregion
}

StaticDowncall(glfwPackage, "GLFWNative", symbolLookup = glfwLookup) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ class InstanceDowncall(
var modifier: String? = null
var constructorModifier: String? = "public"
var constructorParam: String? = null
var handlesConstructorCode: String? = null
var constructorCode: String? = null
var customCode: String? = null
private val extends = mutableListOf<String>()
private val fields = mutableListOf<InstanceDowncallField>()
val descriptorFields = mutableListOf<InstanceDowncallField>()
val handleFields = mutableListOf<InstanceDowncallField>()
val pfnFields = mutableListOf<InstanceDowncallField>()
private val methods = mutableListOf<InstanceDowncallMethod>()
Expand Down Expand Up @@ -67,6 +69,7 @@ class InstanceDowncall(
import java.lang.foreign.*;
import java.lang.invoke.*;
import java.util.*;
import overrungl.annotation.*;
import overrungl.internal.RuntimeHelper;
import overrungl.util.*;
Expand All @@ -86,23 +89,51 @@ class InstanceDowncall(
sb.appendLine(" {")

// fields
fun writeFields(list: List<InstanceDowncallField>) {
fun writeFields(list: List<InstanceDowncallField>, indent: Int) {
list.forEach {
sb.append(" public")
sb.append(" ".repeat(indent))
if (it.modifier != null) {
sb.append(" ")
sb.append(it.modifier)
}
sb.append(" final ${it.type} ${it.name}")
sb.append(" ${it.type} ${it.name}")
if (it.value != null) {
sb.append(" = ${it.value}")
}
sb.appendLine(";")
}
}
writeFields(fields)
writeFields(handleFields)
writeFields(pfnFields)
writeFields(fields, 4)
if (descriptorFields.isNotEmpty()) {
sb.appendLine(" public static final class Descriptors {")
sb.appendLine(" private Descriptors() {}")
writeFields(descriptorFields, 8)
sb.appendLine(" public static final List<FunctionDescriptor> LIST = List.of(")
descriptorFields.forEachIndexed { index, it ->
sb.append(" ${it.name}")
if (index + 1 == descriptorFields.size) {
sb.appendLine()
} else {
sb.appendLine(",")
}
}
sb.appendLine(" );")
sb.appendLine(" }")
}
if (handleFields.isNotEmpty()) {
sb.appendLine(" public static final class Handles {")
writeFields(handleFields, 8)
writeFields(pfnFields, 8)
sb.append(" private Handles(")
if (constructorParam != null) {
sb.append(constructorParam)
}
sb.appendLine(") {")
if (handlesConstructorCode != null) {
sb.appendLine(handlesConstructorCode!!.prependIndent(" "))
}
sb.appendLine(" }")
sb.appendLine(" }")
}

// constructor
sb.appendLine()
Expand All @@ -128,12 +159,12 @@ class InstanceDowncall(
sb.append(m.params.joinToString(", ") { p -> "${p.type.carrierWithC()} ${p.name}" })
sb.appendLine(") {")

sb.appendLine(""" if (Unmarshal.isNullPointer(PFN_${m.entrypoint})) throw new SymbolNotFoundError("Symbol not found: ${m.entrypoint}");""")
sb.appendLine(""" if (Unmarshal.isNullPointer(handles.PFN_${m.entrypoint})) throw new SymbolNotFoundError("Symbol not found: ${m.entrypoint}");""")
sb.append(" try { ")
if (m.returnType.carrier != TypeName.VOID) {
sb.append("return (${m.returnType.carrier}) ")
}
sb.append("MH_${m.entrypoint}.invokeExact(PFN_${m.entrypoint}")
sb.append("Handles.MH_${m.entrypoint}.invokeExact(handles.PFN_${m.entrypoint}")
m.params.forEach {
sb.append(", ${it.name}")
}
Expand All @@ -156,7 +187,7 @@ class InstanceDowncall(
}

data class InstanceDowncallField(
val modifier: String? = null,
val modifier: String?,
val type: String,
val name: String,
val value: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ fun main() {
val longType = get.type == "ull"
field(
InstanceDowncallField(
modifier = "static",
modifier = "public static final",
type = if (longType) "long" else "int",
name = get.name,
value = if (longType) "${get.value}L" else get.value
Expand All @@ -617,19 +617,31 @@ fun main() {

fun InstanceDowncall.addCommand(command: GLRequireCommand) {
val get = commandMap[command.name]!!
// handles

// descriptor
descriptorFields.add(
InstanceDowncallField(
modifier = "public static final",
type = "FunctionDescriptor",
name = "FD_${get.name}",
value = computeFunctionDescriptor(get)
)
)

// handle
handleFields.add(
InstanceDowncallField(
modifier = "static",
modifier = "public static final",
type = "MethodHandle",
name = "MH_${get.name}",
value = "RuntimeHelper.downcall(${computeFunctionDescriptor(get)})"
value = "RuntimeHelper.downcall(Descriptors.FD_${get.name})"
)
)

// address
pfnFields.add(
InstanceDowncallField(
modifier = "public final",
type = "MemorySegment",
name = "PFN_${get.name}"
)
Expand All @@ -652,10 +664,7 @@ fun main() {
InstanceDowncall(openglPackage, "GL${feature.number.replace(".", "")}") {
featureExtends[feature.number]?.also { extends("GL${it}") }
constructorParam = "GLLoadFunc func"
constructorCode = buildString {
if (feature.number != "1.0") {
appendLine("super(func);")
}
handlesConstructorCode = buildString {
val thisFeatureAddedCommand = mutableListOf<String>()
var i = 0
feature.coreForEach(removeCommands, GLRequire::commands) { command ->
Expand All @@ -674,6 +683,12 @@ fun main() {
}
}
}
constructorCode = buildString {
if (feature.number != "1.0") {
appendLine("super(func);")
}
append("this.handles = new Handles(func);")
}
customCode = featureCustomCode(feature.number)

feature.coreForEach(removeEnums, GLRequire::enums) {
Expand All @@ -688,6 +703,9 @@ fun main() {
featureAddedCommands.add(it.name)
}
}
if (handleFields.isNotEmpty()) {
field(InstanceDowncallField(modifier = "private final", type = "Handles", name = "handles"))
}
}
}

Expand Down Expand Up @@ -749,7 +767,7 @@ fun main() {
constructorModifier = "private"
} else {
constructorParam = "overrungl.opengl.GLLoadFunc func"
constructorCode = buildString {
handlesConstructorCode = buildString {
extension.requires.forEach { require ->
require.commands.forEachIndexed { index, command ->
if (index > 0) {
Expand All @@ -762,12 +780,16 @@ fun main() {
}
}
}
constructorCode = "this.handles = new Handles(func);"
}

extension.requires.forEach { require ->
require.enums.forEach(::addEnum)
require.commands.forEach(::addCommand)
}
if (handleFields.isNotEmpty()) {
field(InstanceDowncallField(modifier = "private final", type = "Handles", name = "handles"))
}
}
}
}
Expand Down
57 changes: 44 additions & 13 deletions generators/src/main/kotlin/overrungl/gen/StaticDowncall.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class StaticDowncall(
"""
import java.lang.foreign.*;
import java.lang.invoke.*;
import java.util.*;
import overrungl.annotation.*;
import overrungl.internal.*;
import overrungl.util.*;
Expand Down Expand Up @@ -124,12 +125,7 @@ class StaticDowncall(
sb.appendLine(" //endregion")

if (methods.isNotEmpty()) {
// method handles
sb.appendLine(" //region Method handles")
sb.appendLine(" /// Method handles.")
sb.appendLine(" public static final class Handles {")
sb.appendLine(" private Handles() { }")
mutableListOf<DowncallMethod>().also { l ->
val list = mutableListOf<DowncallMethod>().also { l ->
methods.forEach {
if (it.entrypoint != null) {
val functionDescriptor = it.functionDescriptor
Expand All @@ -140,19 +136,54 @@ class StaticDowncall(
error("Redefining method ${it.name} (entrypoint ${it.entrypoint}, descriptor $functionDescriptor) with method ${m1.name} (entrypoint ${m1.entrypoint}, descriptor ${m1.functionDescriptor})")
}
} else {
sb.appendLine(
"""
| /// The method handle of `${it.entrypoint}`.
| public static final MethodHandle MH_${it.entrypoint} = RuntimeHelper.${if (it.optional) "downcallOrNull" else "downcall"}($symbolLookup, "${it.entrypoint}", $functionDescriptor);
""".trimMargin()
)
l.add(it)
}
}
}
}

// function descriptors
sb.appendLine(" /// Function descriptors.")
sb.appendLine(" public static final class Descriptors {")
sb.appendLine(" private Descriptors() { }")
list.forEach {
sb.appendLine(
"""
| /// The function descriptor of `${it.entrypoint}`.
| public static final FunctionDescriptor FD_${it.entrypoint} = ${it.functionDescriptor};
""".trimMargin()
)
}
sb.appendLine(
"""
| /// Function descriptors.
| public static final List<FunctionDescriptor> LIST = List.of(
""".trimMargin()
)
list.forEachIndexed { index, it ->
sb.append(" FD_${it.entrypoint}")
if (index + 1 == list.size) {
sb.appendLine()
} else {
sb.appendLine(",")
}
}
sb.appendLine(" );")
sb.appendLine(" }")

// method handles
sb.appendLine(" /// Method handles.")
sb.appendLine(" public static final class Handles {")
sb.appendLine(" private Handles() { }")
list.forEach {
sb.appendLine(
"""
| /// The method handle of `${it.entrypoint}`.
| public static final MethodHandle MH_${it.entrypoint} = RuntimeHelper.${if (it.optional) "downcallOrNull" else "downcall"}($symbolLookup, "${it.entrypoint}", Descriptors.FD_${it.entrypoint});
""".trimMargin()
)
}
sb.appendLine(" }")
sb.appendLine(" //endregion")

sb.appendLine()

Expand Down
Loading

0 comments on commit d78146e

Please sign in to comment.