GlueGen: src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java Source File

GlueGen v2.6.0-rc-20250722 GlueGen, Native Binding Generator for Java™ (public API).

ProcAddressCMethodBindingEmitter.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
3 * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * You acknowledge that this software is not designed or intended for use
34 * in the design, construction, operation or maintenance of any nuclear
35 * facility.
36 *
37 * Sun gratefully acknowledges that this software was originally authored
38 * and developed by Kenneth Bradley Russell and Christopher John Kline.
39 */
40
41 package com.jogamp.gluegen.procaddress;
42
43import com.jogamp.gluegen.CMethodBindingEmitter;
44import com.jogamp.gluegen.JavaType;
45import com.jogamp.gluegen.MethodBinding;
46import com.jogamp.gluegen.cgram.types.FunctionSymbol;
47import com.jogamp.gluegen.cgram.types.PointerType;
48import com.jogamp.gluegen.cgram.types.Type;
49
50 public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
51
52 private boolean callThroughProcAddress;
53 private boolean hasProcAddrTypedef;
54
55 private String localTypedefCallingConvention;
56
57 private static final String procAddressJavaTypeName = JavaType.createForClass(Long.TYPE).jniTypeName();
58 private ProcAddressEmitter emitter;
59
60 public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap,
61 final boolean callThroughProcAddress,
62 final boolean hasProcAddrTypedef,
63 final String localTypedefCallingConvention,
64 final ProcAddressEmitter emitter) {
65
66 super(
67 new MethodBinding(methodToWrap.getBinding()) {
68 @Override
69 public String getImplName() {
70 if (callThroughProcAddress) {
71 return ProcAddressEmitter.WRAP_PREFIX + super.getImplName();
72 } else {
73 return super.getImplName();
74 }
75 }
76 },
77 methodToWrap.getUnit(),
78 methodToWrap.getJavaPackageName(),
79 methodToWrap.getJavaClassName(),
80 methodToWrap.getIsOverloadedBinding(),
81 methodToWrap.getIsJavaMethodStatic(),
82 true,
83 methodToWrap.forIndirectBufferAndArrayImplementation(),
84 methodToWrap.getMachineDataInfo(),
85 emitter.getConfig()
86 );
87 if (methodToWrap.getReturnValueCapacityExpression() != null) {
88 setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression());
89 }
90 if (methodToWrap.getReturnValueLengthExpression() != null) {
91 setReturnValueLengthExpression(methodToWrap.getReturnValueLengthExpression());
92 }
93 setTemporaryCVariableDeclarations(methodToWrap.getTemporaryCVariableDeclarations());
94 setTemporaryCVariableAssignments(methodToWrap.getTemporaryCVariableAssignments());
95
96 setCommentEmitter(defaultCommentEmitter);
97
98 this.callThroughProcAddress = callThroughProcAddress;
99 this.hasProcAddrTypedef = hasProcAddrTypedef;
100 this.localTypedefCallingConvention = localTypedefCallingConvention;
101 this.emitter = emitter;
102 }
103
104 @Override
105 protected int appendArguments(final StringBuilder buf) {
106 int numEmitted = super.appendArguments(buf);
107 if (callThroughProcAddress) {
108 if (numEmitted > 0) {
109 buf.append(", ");
110 }
111 buf.append(procAddressJavaTypeName);
112 buf.append(" procAddress");
113 ++numEmitted;
114 }
115 return numEmitted;
116 }
117
118 @Override
119 protected void emitBodyVariableDeclarations() {
120 if (callThroughProcAddress) {
121 // create variable for the function pointer with the right type, and set
122 // it to the value of the passed-in proc address
123 final FunctionSymbol cSym = binding.getCSymbol();
124
125 // Always emit the local typedef, based on our parsing results.
126 // In case we do have the public typedef from the original header,
127 // we use it for the local var and assign our proc-handle to it,
128 // cast to the local typedef.
129 // This allows the native C compiler to validate our types!
130 final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(cSym);
131 final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName;
132 final String funcPointerTypedefName;
133 if (hasProcAddrTypedef) {
134 funcPointerTypedefName = funcPointerTypedefBaseName;
135 } else {
136 funcPointerTypedefName = funcPointerTypedefLocalName;
137 }
138 final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0);
139
140 unit.emit(" typedef ");
141 unit.emit(funcPtrType.toString(funcPointerTypedefLocalName, localTypedefCallingConvention));
142 unit.emitln(";");
143
144 unit.emit(" ");
145 unit.emit(funcPointerTypedefName); // Uses public typedef if available!
146 unit.emit(" ptr_");
147 unit.emit(getNativeName());
148 unit.emitln(";");
149 }
150
151 super.emitBodyVariableDeclarations();
152 }
153
154 @Override
155 protected void emitBodyVariablePreCallSetup() {
156 super.emitBodyVariablePreCallSetup();
157
158 if (callThroughProcAddress) {
159 // set the function pointer to the value of the passed-in procAddress
160 // See above notes in emitBodyVariableDeclarations(..)!
161 final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(binding.getCSymbol());
162 final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName;
163 final String funcPointerTypedefName;
164 if (hasProcAddrTypedef) {
165 funcPointerTypedefName = funcPointerTypedefBaseName;
166 } else {
167 funcPointerTypedefName = funcPointerTypedefLocalName;
168 }
169
170 final String ptrVarName = "ptr_" + getNativeName();
171
172 if (hasProcAddrTypedef) {
173 unit.emitln(" // implicit type validation of "+funcPointerTypedefLocalName+" -> "+funcPointerTypedefName);
174 }
175 unit.emit(" ");
176 unit.emit(ptrVarName);
177 unit.emit(" = (");
178 unit.emit(funcPointerTypedefLocalName);
179 unit.emitln(") (intptr_t) procAddress;");
180
181 unit.emitln(" assert(" + ptrVarName + " != NULL);");
182 }
183 }
184
185 @Override
186 protected void emitBodyCallCFunction() {
187 if (!callThroughProcAddress) {
188 super.emitBodyCallCFunction();
189 } else {
190 // Make the call to the actual C function
191 unit.emit(" ");
192
193 // WARNING: this code assumes that the return type has already been
194 // typedef-resolved.
195 final Type cReturnType = binding.getCReturnType();
196
197 if (!cReturnType.isVoid()) {
198 // Note we respect const/volatile in the function return type.
199 // However, we cannot have it 'const' for our local variable.
200 // See return type in CMethodBindingEmitter.emitBodyVariableDeclarations(..)!
201 unit.emit("_res = (");
202 unit.emit(cReturnType.getCName(false));
203 unit.emit(") ");
204 }
205 final MethodBinding mBinding = getBinding();
206 if (mBinding.hasContainingType()) {
207 // FIXME: this can and should be handled and unified with the
208 // associated code in the CMethodBindingEmitter
209 throw new IllegalStateException("Cannot call through function pointer because binding has containing type: " + mBinding);
210 }
211
212 // call throught the run-time function pointer
213 unit.emit("(* ptr_");
214 unit.emit(getNativeName());
215 unit.emit(") ");
216 unit.emit("(");
217 emitBodyPassCArguments();
218 unit.emitln(");");
219 }
220 }
221
222 @Override
223 protected String jniMangle(final MethodBinding binding) {
224 final StringBuilder buf = new StringBuilder(super.jniMangle(binding));
225 if (callThroughProcAddress && 0 <= buf.indexOf("__") ) {
226 JavaType.appendJNIDescriptor(buf, Long.TYPE, false); // to account for the additional _addr_ parameter
227 }
228 return buf.toString();
229 }
230}
com.jogamp.gluegen.CMethodBindingEmitter
Emits the C-side component of the Java<->C JNI binding to its CodeUnit, see FunctionEmitter.
Definition: CMethodBindingEmitter.java:58
com.jogamp.gluegen.CMethodBindingEmitter.setTemporaryCVariableDeclarations
final void setTemporaryCVariableDeclarations(final List< String > arg)
Sets up a List of Strings containing declarations for temporary C variables to be assigned to after t...
Definition: CMethodBindingEmitter.java:268
com.jogamp.gluegen.CMethodBindingEmitter.defaultCommentEmitter
static final CommentEmitter defaultCommentEmitter
Definition: CMethodBindingEmitter.java:60
com.jogamp.gluegen.CMethodBindingEmitter.setReturnValueCapacityExpression
final void setReturnValueCapacityExpression(final MessageFormat expression)
If this function returns a void* encapsulated in a java.nio.Buffer (or compound type wrapper),...
Definition: CMethodBindingEmitter.java:211
com.jogamp.gluegen.CMethodBindingEmitter.setReturnValueLengthExpression
final void setReturnValueLengthExpression(final MessageFormat expression)
If this function returns an array, sets the expression for the length of the returned array.
Definition: CMethodBindingEmitter.java:244
com.jogamp.gluegen.CMethodBindingEmitter.setTemporaryCVariableAssignments
final void setTemporaryCVariableAssignments(final List< String > arg)
Sets up a List of Strings containing assignments for temporary C variables which are made after the u...
Definition: CMethodBindingEmitter.java:287
com.jogamp.gluegen.FunctionEmitter.setCommentEmitter
void setCommentEmitter(final CommentEmitter cEmitter)
Set the object that will emit the comment for this function.
Definition: FunctionEmitter.java:133
com.jogamp.gluegen.FunctionEmitter.getBinding
final MethodBinding getBinding()
Definition: FunctionEmitter.java:89
com.jogamp.gluegen.JavaEmitter.getConfig
JavaConfiguration getConfig()
Definition: JavaEmitter.java:173
com.jogamp.gluegen.JavaType
Describes a java-side representation of a type that is used to represent the same data on both the Ja...
Definition: JavaType.java:54
com.jogamp.gluegen.JavaType.appendJNIDescriptor
static StringBuilder appendJNIDescriptor(final StringBuilder res, final Class<?> c, final boolean useTrueType)
Appends the native (JNI) method-name descriptor corresponding to the given Class<?...
Definition: JavaType.java:471
com.jogamp.gluegen.JavaType.createForClass
static JavaType createForClass(final Class<?> clazz)
Creates a JavaType corresponding to the given Java type.
Definition: JavaType.java:197
com.jogamp.gluegen.JavaType.jniTypeName
String jniTypeName()
Returns the String corresponding to the JNI type for this type, or NULL if it can't be represented (i...
Definition: JavaType.java:528
com.jogamp.gluegen.MethodBinding
Represents the binding of a C function to a Java method.
Definition: MethodBinding.java:54
com.jogamp.gluegen.MethodBinding.hasContainingType
boolean hasContainingType()
Indicates whether this MethodBinding is for a function pointer contained in a struct,...
Definition: MethodBinding.java:614
com.jogamp.gluegen.cgram.types.FunctionSymbol
Describes a function symbol, which includes the name and type.
Definition: FunctionSymbol.java:63
com.jogamp.gluegen.cgram.types.FunctionSymbol.getType
FunctionType getType()
Returns the type of this function.
Definition: FunctionSymbol.java:95
com.jogamp.gluegen.cgram.types.PointerType
Definition: PointerType.java:44
com.jogamp.gluegen.cgram.types.PointerType.toString
String toString()
Returns a string representation of this type.
Definition: PointerType.java:168
com.jogamp.gluegen.cgram.types.Type
Models a C type.
Definition: Type.java:54
com.jogamp.gluegen.cgram.types.Type.getCName
final String getCName()
Returns the name of this type.
Definition: Type.java:132
com.jogamp.gluegen.cgram.types.Type.isVoid
final boolean isVoid()
Indicates whether this is a VoidType.
Definition: Type.java:415
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter
Definition: ProcAddressCMethodBindingEmitter.java:50
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.emitBodyVariablePreCallSetup
void emitBodyVariablePreCallSetup()
Code to init the variables that were declared in emitBodyVariableDeclarations(), PRIOR TO calling the...
Definition: ProcAddressCMethodBindingEmitter.java:155
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.ProcAddressCMethodBindingEmitter
ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, final boolean callThroughProcAddress, final boolean hasProcAddrTypedef, final String localTypedefCallingConvention, final ProcAddressEmitter emitter)
Definition: ProcAddressCMethodBindingEmitter.java:60
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.jniMangle
String jniMangle(final MethodBinding binding)
Definition: ProcAddressCMethodBindingEmitter.java:223
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.emitBodyVariableDeclarations
void emitBodyVariableDeclarations()
Definition: ProcAddressCMethodBindingEmitter.java:119
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.appendArguments
int appendArguments(final StringBuilder buf)
Returns the number of arguments emitted.
Definition: ProcAddressCMethodBindingEmitter.java:105
com.jogamp.gluegen.procaddress.ProcAddressCMethodBindingEmitter.emitBodyCallCFunction
void emitBodyCallCFunction()
Definition: ProcAddressCMethodBindingEmitter.java:186
com.jogamp.gluegen.procaddress.ProcAddressEmitter
A subclass of JavaEmitter that modifies the normal emission of C and Java code to allow dynamic looku...
Definition: ProcAddressEmitter.java:69
com.jogamp.gluegen.procaddress.ProcAddressEmitter.getFunctionPointerTypedefName
String getFunctionPointerTypedefName(final FunctionSymbol sym)
Returns the name of the typedef for a pointer to the function represented by the argument as defined ...
Definition: ProcAddressEmitter.java:180