GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
MethodBinding.java
Go to the documentation of this file.
1/**
2 * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
3 * Copyright (c) 2003 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
41package com.jogamp.gluegen;
42
43import com.jogamp.gluegen.cgram.types.FunctionSymbol;
44import com.jogamp.gluegen.cgram.types.FunctionType;
45import com.jogamp.gluegen.cgram.types.Type;
46
47import java.util.ArrayList;
48import java.util.List;
49
50/** Represents the binding of a C function to a Java method. Also used
51 to represent calls through function pointers contained in
52 structs. */
53
54public class MethodBinding {
55
56 private final FunctionSymbol sym;
57 private final String delegationImplName;
58 private final JavaType containingType;
59 private final Type containingCType;
60 private String nativeName;
61 private JavaType javaReturnType;
62 private List<JavaType> javaArgumentTypes;
63 private boolean computedSignatureProperties;
64 private boolean argumentsUseNIO;
65 private boolean signatureUsesNIO;
66 private boolean signatureCanUseIndirectNIO;
67 private boolean signatureUsesCompoundTypeWrappers;
68 private boolean signatureUsesArraysOfCompoundTypeWrappers;
69 private boolean signatureUsesCVoidPointers;
70 private boolean signatureUsesCPrimitivePointers;
71 private boolean signatureUsesCArrays;
72 private boolean signatureUsesJavaPrimitiveArrays;
73 private int thisPointerIndex = -1;
74
75 /**
76 * Constructs a new MethodBinding that is an exact clone of the
77 * argument, including the java return type and java argument
78 * types. It's safe to modify this binding after construction.
79 */
80 public MethodBinding(final MethodBinding bindingToCopy) {
81 this.sym = bindingToCopy.sym;
82 this.delegationImplName = bindingToCopy.delegationImplName;
83 this.containingType = bindingToCopy.containingType;
84 this.containingCType = bindingToCopy.containingCType;
85
86 this.nativeName = bindingToCopy.nativeName;
87 this.javaReturnType = bindingToCopy.javaReturnType;
88 this.javaArgumentTypes = ( null != bindingToCopy.javaArgumentTypes ) ? new ArrayList<JavaType>(bindingToCopy.javaArgumentTypes) : null;
89 this.computedSignatureProperties = bindingToCopy.computedSignatureProperties;
90 this.argumentsUseNIO = bindingToCopy.argumentsUseNIO;
91 this.signatureUsesNIO = bindingToCopy.signatureUsesNIO;
92 this.signatureCanUseIndirectNIO = bindingToCopy.signatureCanUseIndirectNIO;
93 this.signatureUsesCompoundTypeWrappers = bindingToCopy.signatureUsesCompoundTypeWrappers;
94 this.signatureUsesArraysOfCompoundTypeWrappers = bindingToCopy.signatureUsesArraysOfCompoundTypeWrappers;
95 this.signatureUsesCVoidPointers = bindingToCopy.signatureUsesCVoidPointers;
96 this.signatureUsesCPrimitivePointers = bindingToCopy.signatureUsesCPrimitivePointers;
97 this.signatureUsesCArrays = bindingToCopy.signatureUsesCArrays;
98 this.signatureUsesJavaPrimitiveArrays = bindingToCopy.signatureUsesJavaPrimitiveArrays;
99 this.thisPointerIndex = bindingToCopy.thisPointerIndex;
100 }
101
102 /**
103 * Constructor for calling a C function or a function pointer contained in a struct.
104 * <p>
105 * In case of the latter, a struct function pointer,
106 * the arguments {@code containingType} and {@code containingCType} must not be {@code null}!
107 * </p>
108 */
110 final String delegationImplName,
111 final JavaType javaReturnType,
112 final List<JavaType> javaArgumentTypes,
113 final JavaType containingType,
114 final Type containingCType) {
115 this.sym = sym;
116 this.delegationImplName = delegationImplName;
117 this.containingType = containingType;
118 this.containingCType = containingCType;
119
120 this.nativeName = null;
121 this.javaReturnType = javaReturnType;
122 this.javaArgumentTypes = javaArgumentTypes;
123 }
124
125 public void setJavaReturnType(final JavaType type) {
126 javaReturnType = type;
127 computedSignatureProperties = false;
128 }
129
130 public void addJavaArgumentType(final JavaType type) {
131 if (javaArgumentTypes == null) {
132 javaArgumentTypes = new ArrayList<JavaType>();
133 }
134 javaArgumentTypes.add(type);
135 computedSignatureProperties = false;
136 }
137
139 return javaReturnType;
140 }
141
142 public int getNumArguments() {
143 return sym.getNumArguments();
144 }
145
146 public JavaType getJavaArgumentType(final int i) {
147 return javaArgumentTypes.get(i);
148 }
149
151 return sym.getReturnType();
152 }
153
154 public Type getCArgumentType(final int i) {
155 return sym.getArgumentType(i);
156 }
157
158 /**
159 * Returns the function parameter list, i.e. a comma separated list of argument type and name.
160 * @param buf StringBuilder instance
161 * @param useTypedef if true and type is typedef'ed, use its name
162 * @param callingConvention optional calling-convention
163 * @return given StringBuilder instance
164 */
165 public StringBuilder getCParameterList(final StringBuilder buf, final boolean useTypedef, final String callingConvention) {
166 return getCParameterList(buf, useTypedef, callingConvention, null);
167 }
168 /**
169 * Returns the function parameter list, i.e. a comma separated list of argument type and name.
170 * @param buf StringBuilder instance
171 * @param useTypedef if true and type is typedef'ed, use its name
172 * @param callingConvention optional calling-convention
173 * @param exclude optional list of excluded parameter indices
174 * @return given StringBuilder instance
175 */
176 public StringBuilder getCParameterList(final StringBuilder buf, final boolean useTypedef, final String callingConvention, final List<Integer> exclude) {
177 forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
178 if( !cType.isVoid() && ( null == exclude || !exclude.contains(idx) ) ) {
179 if( 0 < consumedCount ) {
180 buf.append(", ");
181 }
182 if( useTypedef && cType.isTypedef() ) {
183 buf.append( cType.getName() );
184 if (name != null) {
185 buf.append(" ");
186 buf.append(name);
187 }
188 } else if ( cType.isFunctionPointer() ) {
189 final FunctionType ft = cType.getTargetFunction();
190 buf.append( ft.toString(name, callingConvention, false, true) );
191 } else if (cType.isArray()) {
192 buf.append( cType.asArray().toString(name) );
193 } else {
194 buf.append( cType.getCName(true) );
195 if (name != null) {
196 buf.append(" ");
197 buf.append(name);
198 }
199 }
200 return true;
201 } else {
202 return false;
203 }
204 } );
205 return buf;
206 }
207
208 /**
209 * Returns the function parameter list, i.e. a comma separated list of argument type and name.
210 * @param buf StringBuilder instance
211 * @return given StringBuilder instance
212 */
213 public StringBuilder getJavaParameterList(final StringBuilder buf) {
214 return getJavaParameterList(buf, null);
215 }
216 /**
217 * Returns the function parameter list, i.e. a comma separated list of argument type and name.
218 * @param buf StringBuilder instance
219 * @param exclude optional list of excluded parameter indices
220 * @return given StringBuilder instance
221 */
222 public StringBuilder getJavaParameterList(final StringBuilder buf, final List<Integer> exclude) {
223 forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
224 if( !cType.isVoid() && !jType.isPascalLen() && ( null == exclude || !exclude.contains(idx) ) ) {
225 if( 0 < consumedCount ) {
226 buf.append(", ");
227 }
228 buf.append(jType+" "+name);
229 return true;
230 } else {
231 return false;
232 }
233 } );
234 return buf;
235 }
236 /**
237 * Returns the function parameter list, i.e. a comma separated list of argument type and name.
238 * @param buf StringBuilder instance
239 * @param include list of explicit included parameter indices
240 * @param addTailSeparator add a comma separator in the end if result is not empty
241 * @return given StringBuilder instance
242 */
243 public StringBuilder getJavaSelectParameter(final StringBuilder buf, final List<Integer> include, final boolean addTailSeparator) {
244 forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
245 if( !cType.isVoid() && include.contains(idx) ) {
246 if( 0 < consumedCount ) {
247 buf.append(", ");
248 }
249 buf.append(jType+" "+name);
250 return true;
251 } else {
252 return false;
253 }
254 } );
255 if( addTailSeparator && buf.length() > 0 ) {
256 buf.append(", ");
257 }
258 return buf;
259 }
260 public StringBuilder getJavaCallArgumentList(final StringBuilder buf, final List<Integer> exclude) {
261 forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
262 if( !cType.isVoid() && ( null == exclude || !exclude.contains(idx) ) ) {
263 if( 0 < consumedCount ) {
264 buf.append(", ");
265 }
266 buf.append(name);
267 return true;
268 } else {
269 return false;
270 }
271 } );
272 return buf;
273 }
274 public StringBuilder getJavaCallSelectArguments(final StringBuilder buf, final List<Integer> include, final boolean addTailSeparator) {
275 forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
276 if( !cType.isVoid() && include.contains(idx) ) {
277 if( 0 < consumedCount ) {
278 buf.append(", ");
279 }
280 buf.append(name);
281 return true;
282 } else {
283 return false;
284 }
285 } );
286 if( addTailSeparator && buf.length() > 0 ) {
287 buf.append(", ");
288 }
289 return buf;
290 }
291
292 /** {@link #forEachParameter(ParameterConsumer)} Consumer */
293 public static interface ParameterConsumer {
294 /**
295 * Accept the arguments of the traversed collection element
296 * and return true if consumed. Consumed elements will increased passed `consumedCount` state.
297 * @param idx index of current element, ranges [0 .. size-1]
298 * @param consumedCount number of consumed elements, useful for e.g. `boolean needsSeparator = 0 < consumedCount`
299 * @param cType C Type of argument
300 * @param jType Java Type of argument
301 * @param name argument name
302 * @return true to signal consumed and have traversing loop increment `consumedCount`, otherwise false
303 */
304 boolean accept(int idx, int consumedCount, Type cType, JavaType jType, String name);
305 }
307 final int n = getNumArguments();
308 int consumedCount = 0;
309 for (int i = 0; i < n; i++) {
310 if( c.accept(i, consumedCount, getCArgumentType(i), getJavaArgumentType(i), getArgumentName(i)) ) {
311 ++consumedCount;
312 }
313 }
314 return consumedCount;
315 }
316
317 public final boolean isReturnCompoundByValue() {
318 final Type cReturnType = getCReturnType();
319 if (cReturnType.isVoid()) {
320 return false;
321 }
322 if (javaReturnType.isPrimitive()) {
323 return false;
324 }
325 return !cReturnType.isPointer() && javaReturnType.isCompoundTypeWrapper();
326 }
327
328 /** Returns the {@link FunctionSymbol}. */
330 return sym;
331 }
332
333 /** Returns either the argument name specified by the underlying
334 FunctionSymbol or a fabricated argument name based on the
335 position. Note that it is currently not guaranteed that there
336 are no namespace clashes with these fabricated argument
337 names. */
338 public String getArgumentName(final int i) {
339 final String ret = sym.getArgumentName(i);
340 if ( null != ret ) {
341 return ret;
342 }
343 return "arg" + i;
344 }
345
346 /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name. */
347 public String getName() {
348 return sym.getName();
349 }
350 /**
351 * The
352 * {@link JavaConfiguration#getDelegatedImplementation(com.jogamp.gluegen.cgram.types.AliasedSymbol) implementation delegation}
353 * name, or {@code null} for no delegation.
354 * @see #getImplName()
355 */
356 public String getDelegationImplName() {
357 return delegationImplName;
358 }
359
360 /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name for the interface. */
361 public String getInterfaceName() {
362 return sym.getName();
363 }
364 /**
365 * Returns the {@link FunctionSymbol}'s name for the implementation,
366 * which is the current {@link FunctionSymbol#getName() aliased} API name per default,
367 * or the {@link #getDelegationImplName() delegation} name.
368 * @see #getDelegationImplName()
369 */
370 public String getImplName() {
371 return null != delegationImplName ? delegationImplName : sym.getName();
372 }
373 /**
374 * Returns the {@link FunctionSymbol}'s name for the native function
375 * which is the {@link FunctionSymbol#getOrigName() original} C API name per default,
376 * but may be overridden via {@link #setNativeName(String)}.
377 */
378 public String getNativeName() {
379 return null != nativeName ? nativeName : sym.getOrigName();
380 }
381 public void setNativeName(final String s) { nativeName = s; }
382
383 /** Creates a new MethodBinding replacing the specified Java
384 argument type with a new argument type. If argumentNumber is
385 less than 0 then replaces the return type. */
386 public MethodBinding replaceJavaArgumentType(final int argumentNumber, final JavaType newArgType) {
387
388 final MethodBinding binding = new MethodBinding(this);
389 binding.javaArgumentTypes = null;
390 if (argumentNumber < 0) {
391 binding.setJavaReturnType(newArgType);
392 } else {
393 binding.setJavaReturnType(javaReturnType);
394 }
395 for (int i = 0; i < getNumArguments(); i++) {
396 JavaType type = getJavaArgumentType(i);
397 if (i == argumentNumber) {
398 type = newArgType;
399 }
400 binding.addJavaArgumentType(type);
401 }
402 return binding;
403 }
404
405 /**
406 * Returns true if any of the outgoing arguments in the method's
407 * signature require conversion or checking due to the use of New
408 * I/O.
409 */
410 public boolean argumentsUseNIO() {
411 computeSignatureProperties();
412 return argumentsUseNIO;
413 }
414
415 /**
416 * Returns true if the return type or any of the outgoing arguments
417 * in the method's signature require conversion or checking due to
418 * the use of New I/O.
419 */
420 public boolean signatureUsesNIO() {
421 computeSignatureProperties();
422 return signatureUsesNIO;
423 }
424
425 /**
426 * Returns true if it is possible for any of the outgoing arguments
427 * to be indirect NIO buffers.
428 */
429 public boolean signatureCanUseIndirectNIO() {
430 computeSignatureProperties();
431 return signatureCanUseIndirectNIO;
432 }
433
434 /**
435 * Returns true if the return type or any of the outgoing arguments
436 * in the method's signature use "compound type wrappers", or
437 * NIO-based wrappers for C data structures.
438 */
440 computeSignatureProperties();
441 return signatureUsesCompoundTypeWrappers;
442 }
443
444 /**
445 * Returns true if the return type or any of the outgoing arguments
446 * in the method's signature use arrays of "compound type wrappers",
447 * or NIO-based wrappers for C data structures.
448 */
450 computeSignatureProperties();
451 return signatureUsesArraysOfCompoundTypeWrappers;
452 }
453
454 /**
455 * Returns true if the function needs NIO-related
456 * wrapping/unwrapping or conversion of various arguments. Currently
457 * this returns the logical OR of signatureUsesNIO(),
458 * signatureUsesCompoundTypeWrappers() and signatureUsesArraysOfCompoundTypeWrappers().
459 */
461 return (signatureUsesNIO() || signatureUsesCompoundTypeWrappers() || signatureUsesArraysOfCompoundTypeWrappers() );
462 }
463
464 /**
465 * Returns true if the return type or any of the outgoing arguments
466 * in the method's signature represent C void* pointers.
467 */
468 public boolean signatureUsesCVoidPointers() {
469 computeSignatureProperties();
470 return signatureUsesCVoidPointers;
471 }
472
473 /**
474 * Returns true if the return type or any of the outgoing arguments
475 * in the method's signature represent C primitive pointers.
476 */
478 computeSignatureProperties();
479 return signatureUsesCPrimitivePointers;
480 }
481
482 /**
483 * Returns true if the return type or any of the outgoing arguments
484 * in the method's signature represent C arrays.
485 */
486 public boolean signatureUsesCArrays() {
487 computeSignatureProperties();
488 return signatureUsesCArrays;
489 }
490
491 /**
492 * Returns true if the return type or any of the outgoing arguments
493 * in the method's signature represent Java primitive arrays.
494 */
496 computeSignatureProperties();
497 return signatureUsesJavaPrimitiveArrays;
498 }
499
500 /**
501 * Computes summary information about the method's C and Java
502 * signatures.
503 */
504 protected void computeSignatureProperties() {
505 if (computedSignatureProperties)
506 return;
507
508 argumentsUseNIO = false;
509 signatureUsesNIO = false;
510 signatureCanUseIndirectNIO = false;
511 signatureUsesCompoundTypeWrappers = false;
512 signatureUsesArraysOfCompoundTypeWrappers = false;
513 signatureUsesCVoidPointers = false;
514 signatureUsesCPrimitivePointers = false;
515 signatureUsesCArrays = false;
516 signatureUsesJavaPrimitiveArrays = false;
517
518 if ( javaReturnType.isCompoundTypeWrapper() ) {
519 // Needs wrapping and/or setting of byte order (neither of which
520 // can be done easily from native code)
521 signatureUsesCompoundTypeWrappers = true;
522 }
523
524 if (javaReturnType.isNIOBuffer() ||
525 javaReturnType.isArrayOfCompoundTypeWrappers()) {
526 // Needs setting of byte order and possibly viewing as a
527 // different buffer type which can't be done easily from native
528 // code
529 signatureUsesNIO = true;
530 }
531
532 final Type cRetType = sym.getReturnType();
533 if (cRetType.isArray()) {
534 // Needs checking of array lengths
535 signatureUsesCArrays = true;
536 if (cRetType.asArray().getTargetType().isPrimitive()) {
537 signatureUsesCPrimitivePointers = true;
538 }
539 }
540
541 if (cRetType.isPointer()) {
542 if (cRetType.asPointer().getTargetType().isPrimitive()) {
543 signatureUsesCPrimitivePointers = true;
544 } else if (cRetType.asPointer().getTargetType().isVoid()) {
545 signatureUsesCVoidPointers = true;
546 }
547 }
548
549 for (int i = 0; i < getNumArguments(); i++) {
550 final JavaType javaArgType = getJavaArgumentType(i);
551 final Type cArgType = getCArgumentType(i);
552 if (javaArgType.isCompoundTypeWrapper()) {
553 // Needs unwrapping of accessors
554 signatureUsesCompoundTypeWrappers = true;
555 }
556
557 if (javaArgType.isArrayOfCompoundTypeWrappers()) {
558 // Needs to be duplicated and this array lowered to an array
559 // of Buffers for code emission
560 signatureUsesArraysOfCompoundTypeWrappers = true;
561 }
562
563 if (javaArgType.isNIOBuffer() ||
564 javaArgType.isNIOBufferArray()) {
565 // Needs checking of direct buffer property
566 signatureUsesNIO = true;
567 argumentsUseNIO = true;
568
569 if (javaArgType.isNIOBuffer()) {
570 // Potential conversion to indirect buffer
571 signatureCanUseIndirectNIO = true;
572 }
573 }
574
575 if (cArgType.isArray()) {
576 // Needs checking of array lengths
577 signatureUsesCArrays = true;
578 if (cArgType.asArray().getTargetType().isPrimitive()) {
579 signatureUsesCPrimitivePointers = true;
580 }
581 }
582
583 if (cArgType.isPointer()) {
584 // Handle both real C primitive pointers and any constructions
585 // due to opaque directives
586 if (cArgType.asPointer().getTargetType().isPrimitive() ||
587 javaArgType.isCPrimitivePointerType()) {
588 signatureUsesCPrimitivePointers = true;
589 } else if (cArgType.asPointer().getTargetType().isVoid()) {
590 signatureUsesCVoidPointers = true;
591 }
592 }
593
594 if (javaArgType.isPrimitiveArray()) {
595 // Needs getPrimitiveArrayCritical or similar construct
596 // depending on native code calling convention
597 signatureUsesJavaPrimitiveArrays = true;
598 }
599 }
600
601 computedSignatureProperties = true;
602 }
603
604 /**
605 * Indicates whether this MethodBinding is for a function pointer
606 * contained in a struct, or to access array- or pointer-data from a struct.
607 * <p>
608 * The native calling convention, i.e. via a 'this' function pointer
609 * or by a static native function must be decided in the
610 * {@link JavaEmitter} handling structs and
611 * passed to the {@link CMethodBindingEmitter#setIsCStructFunctionPointer(boolean)}.
612 * </p>
613 */
614 public boolean hasContainingType() {
615 return (getContainingType() != null);
616 }
617
618 /** Retrieves the containing type of this MethodBinding if it is for
619 a function pointer contained in a struct. */
621 return containingType;
622 }
623
624 /** Retrieves the containing C type of this MethodBinding if it is for
625 a function pointer contained in a struct. */
627 return containingCType;
628 }
629
630 /** Find the leftmost argument matching the type of the containing
631 type (for function pointer MethodBindings) and record that as a
632 "this" pointer, meaning that it does not need to be explicitly
633 passed at the Java level. */
634 public void findThisPointer() {
635 clearThisPointer();
636 for (int i = 0; i < getNumArguments(); i++) {
637 final JavaType arg = getJavaArgumentType(i);
638 if (arg.equals(containingType)) {
639 thisPointerIndex = i;
640 break;
641 }
642
643 if (!arg.isJNIEnv()) {
644 break; // this pointer must be leftmost argument excluding JNIEnvs
645 }
646 }
647 }
648
649 /** Clears any record of a this pointer for this MethodBinding. */
650 public void clearThisPointer() {
651 thisPointerIndex = -1;
652 }
653
654 /** Indicates whether the <i>i</i>th argument to this MethodBinding
655 is actually a "this" pointer. */
656 public boolean isArgumentThisPointer(final int i) {
657 return (thisPointerIndex == i);
658 }
659 @Override
660 public boolean equals(final Object obj) {
661 if (obj == this) {
662 return true;
663 }
664
665 if (obj == null || ! (obj instanceof MethodBinding)) {
666 return false;
667 }
668
669 final MethodBinding other = (MethodBinding)obj;
670 if ( !getName().equals(other.getName()) ||
671 !sym.getType().equals(other.sym.getType()) ) { return false; }
672 if (!(javaReturnType.equals(other.getJavaReturnType()))) { return false; }
673 if (containingCType != null &&
674 other.getContainingCType() != null &&
675 (!(containingCType.equals(other.getContainingCType())))) {
676 return false;
677 }
678 if (javaArgumentTypes.size() != other.javaArgumentTypes.size()) {
679 return false;
680 }
681
682 for (int i = 0; i < javaArgumentTypes.size(); ++i) {
683 final Object typeThis = javaArgumentTypes.get(i);
684 final Object typeOther = other.getJavaArgumentType(i);
685 if (!(typeThis.equals(typeOther))) {
686 return false;
687 }
688 }
689
690 return true;
691 }
692
693 @Override
694 public int hashCode() {
695 final StringBuilder buf = new StringBuilder(200);
696 buf.append(getName());
697 buf.append(sym.getType().getName(true));
698 buf.append(getJavaReturnType().getName());
699 if (containingCType != null) {
700 buf.append(containingCType.getName(true));
701 }
702
703 for (int i = 0; i < getNumArguments(); i++) {
704 final JavaType type = getJavaArgumentType(i);
705 if (type.isVoid()) {
706 // Make sure this is the only param to the method; if it isn't,
707 // there's something wrong with our parsing of the headers.
708 assert(getNumArguments() == 1);
709 continue;
710 }
711
712 buf.append(type.getName());
713 }
714 return buf.toString().hashCode();
715 }
716
717 /** Returns the signature of this binding. */
718 @Override
719 public String toString() {
720 final StringBuilder buf = new StringBuilder(200);
721 buf.append(getJavaReturnType().getName());
722 buf.append(' ');
723 buf.append(getName());
724 buf.append('(');
725 boolean needComma = false;
726 for (int i = 0; i < getNumArguments(); i++) {
727 final JavaType type = getJavaArgumentType(i);
728 if (type.isVoid()) {
729 // Make sure this is the only param to the method; if it isn't,
730 // there's something wrong with our parsing of the headers.
731 assert(getNumArguments() == 1);
732 continue;
733 }
734 if (type.isJNIEnv() || type.isPascalLen() || isArgumentThisPointer(i)) {
735 // Don't need to expose these at the Java level
736 continue;
737 }
738
739 if (needComma) {
740 buf.append(", ");
741 }
742
743 buf.append(type.getName());
744 buf.append(' ');
745 buf.append(getArgumentName(i));
746 needComma = true;
747 }
748 buf.append(')');
749 return buf.toString();
750 }
751
752 /** Returns a String containing the descriptor (signature in
753 internal format) of this MethodBinding as it will be
754 emitted. This is used to disambiguate between overloadings when
755 manually specifying prologue and epilogue code, for example. */
756 public String getDescriptor(final boolean forImplementingMethodCall,
757 final boolean eraseBufferAndArrayTypes) {
758 final StringBuilder buf = new StringBuilder();
759
760 buf.append('(');
761
762 if (forImplementingMethodCall && hasContainingType()) {
763 // Always emit outgoing "this" argument
764 buf.append("Ljava/nio/ByteBuffer;");
765 }
766
767 for (int i = 0; i < getNumArguments(); i++) {
768 final JavaType type = getJavaArgumentType(i);
769 if (type.isVoid()) {
770 // Make sure this is the only param to the method; if it isn't,
771 // there's something wrong with our parsing of the headers.
772 if (getNumArguments() != 1) {
773 throw new InternalError(
774 "\"void\" argument type found in " +
775 "multi-argument function \"" + this + "\"");
776 }
777 continue;
778 }
779
780 if (type.isJNIEnv() || isArgumentThisPointer(i)) {
781 // Don't need to expose these at the Java level
782 continue;
783 }
784
785 buf.append(erasedTypeDescriptor(type, eraseBufferAndArrayTypes, false));
786
787 // Add Buffer and array index offset arguments after each associated argument
788 if (forImplementingMethodCall) {
789 if (type.isNIOBuffer()) {
790 buf.append('I');
791 } else if (type.isNIOBufferArray()) {
792 buf.append("[I");
793 }
794 }
795
796 // Add offset argument after each primitive array
797 if (type.isPrimitiveArray()) {
798 buf.append('I');
799 }
800 }
801
802 buf.append(')');
803
804 // Emit return type for completeness even though we can't overload
805 // based solely on return type
806 buf.append(erasedTypeDescriptor(getJavaReturnType(), eraseBufferAndArrayTypes, false));
807
808 return buf.toString();
809 }
810
811 protected String erasedTypeDescriptor(final JavaType type, final boolean eraseBufferAndArrayTypes, final boolean skipBuffers) {
812 if (eraseBufferAndArrayTypes) {
813 if (type.isNIOBuffer() ||
814 type.isPrimitiveArray()) {
815 if (!skipBuffers) {
816 // Direct buffers and arrays sent down as Object (but
817 // returned as e.g. ByteBuffer)
818 return "Ljava/lang/Object;";
819 }
820 } else if (type.isCompoundTypeWrapper()) {
821 // Compound type wrappers are unwrapped to ByteBuffer
822 return "Ljava/nio/ByteBuffer;";
823 } else if (type.isArrayOfCompoundTypeWrappers()) {
824 return "Ljava/nio/ByteBuffer;";
825 }
826 }
827 return type.getDescriptor();
828 }
829}
830
Describes a java-side representation of a type that is used to represent the same data on both the Ja...
Definition: JavaType.java:54
boolean equals(final Object arg)
Definition: JavaType.java:138
String getName()
Returns the Java type name corresponding to this type.
Definition: JavaType.java:339
String getDescriptor()
Returns the descriptor (internal type signature) corresponding to this type.
Definition: JavaType.java:362
boolean isArrayOfCompoundTypeWrappers()
Definition: JavaType.java:709
Represents the binding of a C function to a Java method.
String erasedTypeDescriptor(final JavaType type, final boolean eraseBufferAndArrayTypes, final boolean skipBuffers)
MethodBinding(final MethodBinding bindingToCopy)
Constructs a new MethodBinding that is an exact clone of the argument, including the java return type...
boolean signatureUsesCVoidPointers()
Returns true if the return type or any of the outgoing arguments in the method's signature represent ...
boolean signatureCanUseIndirectNIO()
Returns true if it is possible for any of the outgoing arguments to be indirect NIO buffers.
String getArgumentName(final int i)
Returns either the argument name specified by the underlying FunctionSymbol or a fabricated argument ...
void computeSignatureProperties()
Computes summary information about the method's C and Java signatures.
StringBuilder getJavaCallSelectArguments(final StringBuilder buf, final List< Integer > include, final boolean addTailSeparator)
int forEachParameter(final ParameterConsumer c)
boolean signatureUsesCompoundTypeWrappers()
Returns true if the return type or any of the outgoing arguments in the method's signature use "compo...
StringBuilder getJavaParameterList(final StringBuilder buf)
Returns the function parameter list, i.e.
Type getContainingCType()
Retrieves the containing C type of this MethodBinding if it is for a function pointer contained in a ...
String getImplName()
Returns the FunctionSymbol's name for the implementation, which is the current aliased API name per d...
StringBuilder getCParameterList(final StringBuilder buf, final boolean useTypedef, final String callingConvention, final List< Integer > exclude)
Returns the function parameter list, i.e.
String getDescriptor(final boolean forImplementingMethodCall, final boolean eraseBufferAndArrayTypes)
Returns a String containing the descriptor (signature in internal format) of this MethodBinding as it...
StringBuilder getJavaSelectParameter(final StringBuilder buf, final List< Integer > include, final boolean addTailSeparator)
Returns the function parameter list, i.e.
JavaType getContainingType()
Retrieves the containing type of this MethodBinding if it is for a function pointer contained in a st...
JavaType getJavaArgumentType(final int i)
void findThisPointer()
Find the leftmost argument matching the type of the containing type (for function pointer MethodBindi...
String getInterfaceName()
Returns the FunctionSymbol's current aliased API name for the interface.
String getName()
Returns the FunctionSymbol's current aliased API name.
boolean signatureUsesCPrimitivePointers()
Returns true if the return type or any of the outgoing arguments in the method's signature represent ...
MethodBinding replaceJavaArgumentType(final int argumentNumber, final JavaType newArgType)
Creates a new MethodBinding replacing the specified Java argument type with a new argument type.
void addJavaArgumentType(final JavaType type)
boolean hasContainingType()
Indicates whether this MethodBinding is for a function pointer contained in a struct,...
StringBuilder getJavaParameterList(final StringBuilder buf, final List< Integer > exclude)
Returns the function parameter list, i.e.
boolean argumentsUseNIO()
Returns true if any of the outgoing arguments in the method's signature require conversion or checkin...
boolean signatureUsesArraysOfCompoundTypeWrappers()
Returns true if the return type or any of the outgoing arguments in the method's signature use arrays...
String toString()
Returns the signature of this binding.
void setJavaReturnType(final JavaType type)
boolean isArgumentThisPointer(final int i)
Indicates whether the ith argument to this MethodBinding is actually a "this" pointer.
FunctionSymbol getCSymbol()
Returns the FunctionSymbol.
void setNativeName(final String s)
StringBuilder getJavaCallArgumentList(final StringBuilder buf, final List< Integer > exclude)
boolean signatureUsesNIO()
Returns true if the return type or any of the outgoing arguments in the method's signature require co...
String getNativeName()
Returns the FunctionSymbol's name for the native function which is the original C API name per defaul...
boolean signatureUsesJavaPrimitiveArrays()
Returns true if the return type or any of the outgoing arguments in the method's signature represent ...
boolean signatureUsesCArrays()
Returns true if the return type or any of the outgoing arguments in the method's signature represent ...
boolean equals(final Object obj)
MethodBinding(final FunctionSymbol sym, final String delegationImplName, final JavaType javaReturnType, final List< JavaType > javaArgumentTypes, final JavaType containingType, final Type containingCType)
Constructor for calling a C function or a function pointer contained in a struct.
StringBuilder getCParameterList(final StringBuilder buf, final boolean useTypedef, final String callingConvention)
Returns the function parameter list, i.e.
void clearThisPointer()
Clears any record of a this pointer for this MethodBinding.
String getDelegationImplName()
The implementation delegation name, or null for no delegation.
boolean needsNIOWrappingOrUnwrapping()
Returns true if the function needs NIO-related wrapping/unwrapping or conversion of various arguments...
final Type getTargetType()
Helper method to returns the target type of this type, in case another type is being referenced,...
Definition: ArrayType.java:115
Describes a function symbol, which includes the name and type.
FunctionType getType()
Returns the type of this function.
Type getArgumentType(final int i)
Returns the type of the ith argument.
Type getReturnType()
Returns the return type of this function.
final Type getTargetType()
Helper method to returns the target type of this type, in case another type is being referenced,...
final boolean isArray()
Indicates whether this is an ArrayType.
Definition: Type.java:409
final boolean isVoid()
Indicates whether this is a VoidType.
Definition: Type.java:415
boolean isFunctionPointer()
Convenience routine indicating whether this Type is a pointer to a function.
Definition: Type.java:430
PointerType asPointer()
Casts this to a PointerType or returns null if not a PointerType.
Definition: Type.java:386
boolean isPrimitive()
Indicates whether this type is a primitive type.
Definition: Type.java:426
ArrayType asArray()
Casts this to an ArrayType or returns null if not an ArrayType.
Definition: Type.java:388
final boolean isPointer()
Indicates whether this is a PointerType.
Definition: Type.java:407
forEachParameter(ParameterConsumer) Consumer
boolean accept(int idx, int consumedCount, Type cType, JavaType jType, String name)
Accept the arguments of the traversed collection element and return true if consumed.