private String buildSignatureString(Class<?>[] arguments, Class<?> returnClazz) { String sig = "("; for (Class<?> arg : arguments) { if (!arg.isPrimitive()) sig += "L" + getMethodStyleName(arg) + ";"; else sig += getMethodStyleName(arg); } sig += ")"; if (!returnClazz.isPrimitive()) { sig += "L" + getMethodStyleName(returnClazz) + ";"; } else { sig += getMethodStyleName(returnClazz); } return sig; }
@Override public Schema outputSchema(Schema input) { if (!isInitialized) initialize(); return outputSchema; }
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", new String[] { "org/apache/pig/builtin/InvokerFunction" }); makeConstructor(cw); loadAndStoreArgument(mv, begin++, next++, getMethodStyleName(method.getDeclaringClass())); loadAndStoreArgument(mv, i + begin, next++, getMethodStyleName(getObjectVersion(arguments[i]))); unboxIfPrimitive(mv, arg); String signature = buildSignatureString(arguments, method.getReturnType()); mv.visitMethodInsn(isStatic ? INVOKESTATIC : isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, getMethodStyleName(method.getDeclaringClass()), method.getName(), signature); boxIfPrimitive(mv, method.getReturnType()); //TODO does this work? mv.visitInsn(ARETURN); mv.visitMaxs(2, (isStatic ? 2 : 3) + arguments.length);
Class<?>[] arguments = getArgumentClassArray(argumentTypes_); outputSchema.add(new Schema.FieldSchema(null, type)); generatedFunction = generateInvokerFunction("InvokerFunction_"+getUniqueId(), method, isStatic, arguments);
private void loadAndStoreArgument(MethodVisitor mv, int loadIdx, int storeIdx, String castName) { mv.visitVarInsn(ALOAD, 1); //loads the 1st argument addConst(mv, loadIdx); mv.visitMethodInsn(INVOKEINTERFACE, "org/apache/pig/data/Tuple", "get", "(I)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, castName); mv.visitVarInsn(ASTORE, storeIdx); }
private InvokerFunction generateInvokerFunction(String className, Method method, boolean isStatic, Class<?>[] arguments) { byte[] byteCode = generateInvokerFunctionBytecode(className, method, isStatic, arguments); return ByteClassLoader.getInvokerFunction(className, byteCode); }
private void unboxIfPrimitive(MethodVisitor mv, Class<?> clazz) { if (!clazz.isPrimitive()) { return; } String methodName = clazz.getSimpleName()+"Value"; mv.visitMethodInsn(INVOKEVIRTUAL, getMethodStyleName(inverseTypeMap.get(clazz)), methodName, "()"+getMethodStyleName(clazz)); }
@Override public Object exec(Tuple input) throws IOException { if (!isInitialized) initialize(); return generatedFunction.eval(input); }
private void boxIfPrimitive(MethodVisitor mv, Class<?> clazz) { if (!clazz.isPrimitive()) { return; } String boxedClass = getMethodStyleName(inverseTypeMap.get(clazz)); mv.visitMethodInsn(INVOKESTATIC, boxedClass, "valueOf", "("+getMethodStyleName(clazz)+")L"+boxedClass+";"); }