protected boolean installSyntheticVTablePtr(Type type, NativeLibrary library, Pointer<?> peer) { synchronized (syntheticVirtualTables) { VTable vtable = syntheticVirtualTables.get(type); if (vtable == null) { if (!typesThatDontNeedASyntheticVirtualTable.contains(type)) { List<VirtMeth> methods = new ArrayList<VirtMeth>(); listVirtualMethods(Utils.getClass(type), methods); boolean needsASyntheticVirtualTable = false; for (VirtMeth method : methods) if (!Modifier.isNative(method.implementation.getModifiers())) { needsASyntheticVirtualTable = true; break; } if (needsASyntheticVirtualTable) { Type parentType = Utils.getParent(type); Pointer<Pointer> parentVTablePtr = null; if (CPPObject.class.isAssignableFrom(Utils.getClass(parentType))) { parentVTablePtr = peer.getPointer(Pointer.class); if (BridJ.debug) { BridJ.info( "Found parent virtual table pointer = " + ptrToString(parentVTablePtr, library)); /*Pointer<Pointer> expectedParentVTablePtr = pointerToAddress(getVirtualTable(parentType, library), Pointer.class); if (expectedParentVTablePtr != null && !Utils.eq(parentVTablePtr, expectedParentVTablePtr)) BridJ.warning("Weird parent virtual table pointer : expected " + ptrToString(expectedParentVTablePtr, library) + ", got " + ptrToString(parentVTablePtr, library)); */ } // parentVTablePtr = pointerToAddress(getVirtualTable(parentType, library), // Pointer.class); } syntheticVirtualTables.put( type, vtable = synthetizeVirtualTable(type, parentVTablePtr, methods, library)); } else { typesThatDontNeedASyntheticVirtualTable.add(type); } } } if (vtable != null) { if (BridJ.debug) BridJ.info( "Installing synthetic vtable pointer " + vtable.ptr + " to instance at " + peer + " (type = " + Utils.toString(type) + ", " + vtable.callbacks.size() + " callbacks)"); peer.setPointer(vtable.ptr); return vtable.ptr != null; } else return false; } }