use of org.mvel2.asm.Label in project drools by kiegroup.
the class DefaultBeanClassBuilder method buildConstructorWithFields.
/**
* Creates a constructor that takes and assigns values to all
* fields in the order they are declared.
*
* @param cw
* @param classDef
*/
protected void buildConstructorWithFields(ClassVisitor cw, ClassDefinition classDef, Collection<FieldDefinition> fieldDefs) {
Type[] params = new Type[fieldDefs.size()];
int index = 0;
for (FieldDefinition field : fieldDefs) {
params[index++] = Type.getType(BuildUtils.getTypeDescriptor(field.getTypeName()));
}
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, params), null, null);
mv.visitCode();
Label l0 = null;
if (this.debug) {
l0 = new Label();
mv.visitLabel(l0);
}
fieldConstructorStart(mv, classDef, fieldDefs);
mv.visitInsn(Opcodes.RETURN);
Label l1 = null;
if (this.debug) {
l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, l1, 0);
for (FieldDefinition field : classDef.getFieldsDefinitions()) {
Label l11 = new Label();
mv.visitLabel(l11);
mv.visitLocalVariable(field.getName(), BuildUtils.getTypeDescriptor(field.getTypeName()), null, l0, l1, 0);
}
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
use of org.mvel2.asm.Label in project drools by kiegroup.
the class DefaultBeanClassBuilder method buildDefaultConstructor.
/**
* Creates a default constructor for the class
*
* @param cw
*/
protected void buildDefaultConstructor(ClassVisitor cw, ClassDefinition classDef) {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
mv.visitCode();
Label l0 = null;
if (this.debug) {
l0 = new Label();
mv.visitLabel(l0);
}
boolean hasObjects = defaultConstructorStart(mv, classDef);
mv.visitInsn(Opcodes.RETURN);
Label l1 = null;
if (this.debug) {
l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, l1, 0);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
use of org.mvel2.asm.Label in project drools by kiegroup.
the class ASMEvalStubBuilder method createStubEval.
private void createStubEval(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
generator.setInterfaces(EvalStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "eval", EvalExpression.class);
generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "clone", generator.methodDescr(EvalExpression.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
String internalClassName = generator.getClassName().replace('.', '/');
mv.visitTypeInsn(NEW, internalClassName);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, internalClassName, "<init>", "()V", false);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(Boolean.TYPE, Tuple.class, Declaration[].class, ReteEvaluator.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
Label syncStart = new Label();
Label syncEnd = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(syncStart, l1, l2, null);
Label l3 = new Label();
mv.visitTryCatchBlock(l2, l3, l2, null);
getFieldFromThis("eval", EvalExpression.class);
mv.visitJumpInsn(IFNONNULL, syncEnd);
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, 5);
// synchronized(this) {
mv.visitInsn(MONITORENTER);
mv.visitLabel(syncStart);
getFieldFromThis("eval", EvalExpression.class);
// if (eval == null) ...
Label ifNotInitialized = new Label();
mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
// ... EvalGenerator.generate(this, tuple, declarations, workingMemory)
invokeStatic(EvalGenerator.class, "generate", null, EvalStub.class, Tuple.class, Declaration[].class, ReteEvaluator.class);
mv.visitLabel(ifNotInitialized);
mv.visitVarInsn(ALOAD, 5);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l1);
mv.visitJumpInsn(GOTO, syncEnd);
mv.visitLabel(l2);
mv.visitVarInsn(ASTORE, 6);
mv.visitVarInsn(ALOAD, 5);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, 6);
mv.visitInsn(ATHROW);
mv.visitLabel(syncEnd);
// } end of synchronized
getFieldFromThis("eval", EvalExpression.class);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
invokeInterface(EvalExpression.class, "evaluate", Boolean.TYPE, Tuple.class, Declaration[].class, ReteEvaluator.class, Object.class);
mv.visitInsn(IRETURN);
}
}).addMethod(ACC_PUBLIC, "setEval", generator.methodDescr(null, EvalExpression.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
putFieldInThisFromRegistry("eval", EvalExpression.class, 1);
mv.visitInsn(RETURN);
}
});
}
use of org.mvel2.asm.Label in project drools by kiegroup.
the class ASMPredicateStubBuilder method createStubPredicate.
private void createStubPredicate(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
generator.setInterfaces(PredicateStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "predicate", PredicateExpression.class);
generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
Label syncStart = new Label();
Label syncEnd = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(syncStart, l1, l2, null);
Label l3 = new Label();
mv.visitTryCatchBlock(l2, l3, l2, null);
getFieldFromThis("predicate", PredicateExpression.class);
mv.visitJumpInsn(IFNONNULL, syncEnd);
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, 7);
// synchronized(this) {
mv.visitInsn(MONITORENTER);
mv.visitLabel(syncStart);
getFieldFromThis("predicate", PredicateExpression.class);
// if (predicate == null) ...
Label ifNotInitialized = new Label();
mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 5);
// ... PredicateGenerator.generate(this, tuple, declarations, declarations, workingMemory)
invokeStatic(PredicateGenerator.class, "generate", null, PredicateStub.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class);
mv.visitLabel(ifNotInitialized);
mv.visitVarInsn(ALOAD, 7);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l1);
mv.visitJumpInsn(GOTO, syncEnd);
mv.visitLabel(l2);
mv.visitVarInsn(ASTORE, 8);
mv.visitVarInsn(ALOAD, 7);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, 8);
mv.visitInsn(ATHROW);
mv.visitLabel(syncEnd);
// } end of synchronized
getFieldFromThis("predicate", PredicateExpression.class);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 5);
mv.visitVarInsn(ALOAD, 6);
invokeInterface(PredicateExpression.class, "evaluate", Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class, Object.class);
mv.visitInsn(IRETURN);
}
}).addMethod(ACC_PUBLIC, "setPredicate", generator.methodDescr(null, PredicateExpression.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
putFieldInThisFromRegistry("predicate", PredicateExpression.class, 1);
mv.visitInsn(RETURN);
}
});
}
use of org.mvel2.asm.Label in project mvel by mvel.
the class ASMAccessorOptimizer method getMethod.
@SuppressWarnings({ "unchecked" })
private Object getMethod(Object ctx, String name) throws IllegalAccessException, InvocationTargetException {
assert debug("\n ** {method: " + name + "}");
int st = cursor;
String tk = cursor != end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, '(')) - st) > 1 ? new String(expr, st + 1, cursor - st - 1) : "";
cursor++;
Object[] preConvArgs;
Object[] args;
Class[] argTypes;
ExecutableStatement[] es;
List<char[]> subtokens;
if (tk.length() == 0) {
args = preConvArgs = ParseTools.EMPTY_OBJ_ARR;
argTypes = ParseTools.EMPTY_CLS_ARR;
es = null;
subtokens = null;
} else {
subtokens = parseParameterList(tk.toCharArray(), 0, -1);
es = new ExecutableStatement[subtokens.size()];
args = new Object[subtokens.size()];
argTypes = new Class[subtokens.size()];
preConvArgs = new Object[es.length];
for (int i = 0; i < subtokens.size(); i++) {
assert debug("subtoken[" + i + "] { " + new String(subtokens.get(i)) + " }");
preConvArgs[i] = args[i] = (es[i] = (ExecutableStatement) subCompileExpression(subtokens.get(i), pCtx)).getValue(this.thisRef, this.thisRef, variableFactory);
if (es[i].isExplicitCast())
argTypes[i] = es[i].getKnownEgressType();
}
if (pCtx.isStrictTypeEnforcement()) {
for (int i = 0; i < args.length; i++) {
argTypes[i] = es[i].getKnownEgressType();
if (es[i] instanceof ExecutableLiteral && ((ExecutableLiteral) es[i]).getLiteral() == null) {
argTypes[i] = NullType.class;
}
}
} else {
for (int i = 0; i < args.length; i++) {
if (argTypes[i] != null)
continue;
if (es[i].getKnownEgressType() == Object.class) {
argTypes[i] = args[i] == null ? null : args[i].getClass();
} else {
argTypes[i] = es[i].getKnownEgressType();
}
}
}
}
if (first && variableFactory != null && variableFactory.isResolveable(name)) {
Object ptr = variableFactory.getVariableResolver(name).getValue();
if (ptr instanceof Method) {
ctx = ((Method) ptr).getDeclaringClass();
name = ((Method) ptr).getName();
} else if (ptr instanceof MethodStub) {
ctx = ((MethodStub) ptr).getClassReference();
name = ((MethodStub) ptr).getMethodName();
} else if (ptr instanceof FunctionInstance) {
if (es != null && es.length != 0) {
compiledInputs.addAll(Arrays.asList(es));
intPush(es.length);
assert debug("ANEWARRAY [" + es.length + "]");
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
assert debug("ASTORE 4");
mv.visitVarInsn(ASTORE, 4);
for (int i = 0; i < es.length; i++) {
assert debug("ALOAD 4");
mv.visitVarInsn(ALOAD, 4);
intPush(i);
loadField(i);
assert debug("ALOAD 1");
mv.visitVarInsn(ALOAD, 1);
assert debug("ALOAD 3");
mv.visitIntInsn(ALOAD, 3);
assert debug("INVOKEINTERFACE ExecutableStatement.getValue");
mv.visitMethodInsn(INVOKEINTERFACE, NAMESPACE + "compiler/ExecutableStatement", "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
assert debug("AASTORE");
mv.visitInsn(AASTORE);
}
} else {
assert debug("ACONST_NULL");
mv.visitInsn(ACONST_NULL);
assert debug("CHECKCAST java/lang/Object");
mv.visitTypeInsn(CHECKCAST, "[Ljava/lang/Object;");
assert debug("ASTORE 4");
mv.visitVarInsn(ASTORE, 4);
}
if (variableFactory.isIndexedFactory() && variableFactory.isTarget(name)) {
loadVariableByIndex(variableFactory.variableIndexOf(name));
} else {
loadVariableByName(name);
}
checkcast(FunctionInstance.class);
assert debug("ALOAD 1");
mv.visitVarInsn(ALOAD, 1);
assert debug("ALOAD 2");
mv.visitVarInsn(ALOAD, 2);
assert debug("ALOAD 3");
mv.visitVarInsn(ALOAD, 3);
assert debug("ALOAD 4");
mv.visitVarInsn(ALOAD, 4);
assert debug("INVOKEVIRTUAL Function.call");
mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(FunctionInstance.class), "call", "(Ljava/lang/Object;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;[Ljava/lang/Object;)Ljava/lang/Object;");
return ((FunctionInstance) ptr).call(ctx, thisRef, variableFactory, args);
} else {
throw new OptimizationFailure("attempt to optimize a method call for a reference that does not point to a method: " + name + " (reference is type: " + (ctx != null ? ctx.getClass().getName() : null) + ")");
}
first = false;
} else if (returnType != null && returnType.isPrimitive()) {
// noinspection unchecked
wrapPrimitive(returnType);
}
/**
* If the target object is an instance of java.lang.Class itself then do not
* adjust the Class scope target.
*/
boolean classTarget = false;
Class<?> cls = currType != null ? currType : ((classTarget = ctx instanceof Class) ? (Class<?>) ctx : ctx.getClass());
currType = null;
Method m;
Class[] parameterTypes = null;
/**
* Try to find an instance method from the class target.
*/
if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
parameterTypes = m.getParameterTypes();
}
if (m == null && classTarget) {
/**
* If we didn't find anything, maybe we're looking for the actual java.lang.Class methods.
*/
if ((m = getBestCandidate(argTypes, name, cls, Class.class.getMethods(), false)) != null) {
parameterTypes = m.getParameterTypes();
}
}
// If we didn't find anything and the declared class is different from the actual one try also with the actual one
if (m == null && cls != ctx.getClass() && !(ctx instanceof Class)) {
cls = ctx.getClass();
if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
parameterTypes = m.getParameterTypes();
}
}
if (es != null && m != null && m.isVarArgs() && (es.length != parameterTypes.length || !(es[es.length - 1] instanceof ExecutableAccessor))) {
// normalize ExecutableStatement for varargs
ExecutableStatement[] varArgEs = new ExecutableStatement[parameterTypes.length];
int varArgStart = parameterTypes.length - 1;
for (int i = 0; i < varArgStart; i++) varArgEs[i] = es[i];
String varargsTypeName = parameterTypes[parameterTypes.length - 1].getComponentType().getName();
String varArgExpr;
if ("null".equals(tk)) {
// if null is the token no need for wrapping
varArgExpr = tk;
} else {
StringBuilder sb = new StringBuilder("new ").append(varargsTypeName).append("[] {");
for (int i = varArgStart; i < subtokens.size(); i++) {
sb.append(subtokens.get(i));
if (i < subtokens.size() - 1)
sb.append(",");
}
varArgExpr = sb.append("}").toString();
}
char[] token = varArgExpr.toCharArray();
varArgEs[varArgStart] = ((ExecutableStatement) subCompileExpression(token, pCtx));
es = varArgEs;
if (preConvArgs.length == parameterTypes.length - 1) {
// empty vararg
Object[] preConvArgsForVarArg = new Object[parameterTypes.length];
for (int i = 0; i < preConvArgs.length; i++) preConvArgsForVarArg[i] = preConvArgs[i];
preConvArgsForVarArg[parameterTypes.length - 1] = Array.newInstance(parameterTypes[parameterTypes.length - 1].getComponentType(), 0);
preConvArgs = preConvArgsForVarArg;
}
}
int inputsOffset = compiledInputs.size();
if (es != null) {
for (ExecutableStatement e : es) {
if (e instanceof ExecutableLiteral) {
continue;
}
compiledInputs.add(e);
}
}
if (first) {
assert debug("ALOAD 1 (D) ");
mv.visitVarInsn(ALOAD, 1);
}
if (m == null) {
StringAppender errorBuild = new StringAppender();
if (parameterTypes != null) {
for (int i = 0; i < args.length; i++) {
errorBuild.append(parameterTypes[i] != null ? parameterTypes[i].getClass().getName() : null);
if (i < args.length - 1)
errorBuild.append(", ");
}
}
if ("size".equals(name) && args.length == 0 && cls.isArray()) {
anyArrayCheck(cls);
assert debug("ARRAYLENGTH");
mv.visitInsn(ARRAYLENGTH);
wrapPrimitive(int.class);
return getLength(ctx);
}
throw new CompileException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", expr, st);
} else {
m = getWidenedTarget(m);
if (es != null) {
ExecutableStatement cExpr;
for (int i = 0; i < es.length; i++) {
if ((cExpr = es[i]).getKnownIngressType() == null) {
cExpr.setKnownIngressType(parameterTypes[i]);
cExpr.computeTypeConversionRule();
}
if (!cExpr.isConvertableIngressEgress() && i < args.length) {
args[i] = convert(args[i], paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
}
}
} else {
/**
* Coerce any types if required.
*/
for (int i = 0; i < args.length; i++) {
args[i] = convert(args[i], paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
}
}
Class<?> declaringClass = m.getDeclaringClass();
if (m.getParameterTypes().length == 0) {
if ((m.getModifiers() & STATIC) != 0) {
assert debug("INVOKESTATIC " + m.getName());
mv.visitMethodInsn(INVOKESTATIC, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
} else {
assert debug("CHECKCAST " + getInternalName(declaringClass));
mv.visitTypeInsn(CHECKCAST, getInternalName(declaringClass));
if (declaringClass.isInterface()) {
assert debug("INVOKEINTERFACE " + m.getName());
mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
} else {
assert debug("INVOKEVIRTUAL " + m.getName());
mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
}
}
returnType = m.getReturnType();
stacksize++;
} else {
if ((m.getModifiers() & STATIC) == 0) {
assert debug("CHECKCAST " + getInternalName(declaringClass));
mv.visitTypeInsn(CHECKCAST, getInternalName(declaringClass));
}
for (int i = 0; es != null && i < es.length; i++) {
if (es[i] instanceof ExecutableLiteral) {
ExecutableLiteral literal = (ExecutableLiteral) es[i];
if (literal.getLiteral() == null) {
assert debug("ICONST_NULL");
mv.visitInsn(ACONST_NULL);
continue;
} else if (parameterTypes[i] == int.class && literal.intOptimized()) {
intPush(literal.getInteger32());
continue;
} else if (parameterTypes[i] == int.class && preConvArgs[i] instanceof Integer) {
intPush((Integer) preConvArgs[i]);
continue;
} else if (parameterTypes[i] == boolean.class) {
boolean bool = DataConversion.convert(literal.getLiteral(), Boolean.class);
assert debug(bool ? "ICONST_1" : "ICONST_0");
mv.visitInsn(bool ? ICONST_1 : ICONST_0);
continue;
} else {
Object lit = literal.getLiteral();
if (parameterTypes[i] == Object.class) {
if (isPrimitiveWrapper(lit.getClass())) {
if (lit.getClass() == Integer.class) {
intPush((Integer) lit);
} else {
assert debug("LDC " + lit);
mv.visitLdcInsn(lit);
}
wrapPrimitive(lit.getClass());
} else if (lit instanceof String) {
mv.visitLdcInsn(lit);
checkcast(Object.class);
}
continue;
} else if (canConvert(parameterTypes[i], lit.getClass())) {
Object c = convert(lit, parameterTypes[i]);
if (c instanceof Class) {
ldcClassConstant((Class) c);
} else {
assert debug("LDC " + lit + " (" + lit.getClass().getName() + ")");
mv.visitLdcInsn(c);
if (isPrimitiveWrapper(parameterTypes[i])) {
wrapPrimitive(lit.getClass());
}
}
continue;
} else {
throw new OptimizationNotSupported();
}
}
}
assert debug("ALOAD 0");
mv.visitVarInsn(ALOAD, 0);
assert debug("GETFIELD p" + inputsOffset);
mv.visitFieldInsn(GETFIELD, className, "p" + inputsOffset, "L" + NAMESPACE + "compiler/ExecutableStatement;");
inputsOffset++;
assert debug("ALOAD 2");
mv.visitVarInsn(ALOAD, 2);
assert debug("ALOAD 3");
mv.visitVarInsn(ALOAD, 3);
assert debug("INVOKEINTERFACE ExecutableStatement.getValue");
mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(ExecutableStatement.class), "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
if (parameterTypes[i].isPrimitive()) {
if (preConvArgs[i] == null || (parameterTypes[i] != String.class && !parameterTypes[i].isAssignableFrom(preConvArgs[i].getClass()))) {
ldcClassConstant(getWrapperClass(parameterTypes[i]));
assert debug("INVOKESTATIC DataConversion.convert");
mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
}
unwrapPrimitive(parameterTypes[i]);
} else if (preConvArgs[i] == null || (parameterTypes[i] != String.class && !parameterTypes[i].isAssignableFrom(preConvArgs[i].getClass()))) {
ldcClassConstant(parameterTypes[i]);
assert debug("INVOKESTATIC DataConversion.convert");
mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
assert debug("CHECKCAST " + getInternalName(parameterTypes[i]));
mv.visitTypeInsn(CHECKCAST, getInternalName(parameterTypes[i]));
} else if (parameterTypes[i] == String.class) {
assert debug("<<<DYNAMIC TYPE OPTIMIZATION STRING>>");
mv.visitVarInsn(ASTORE, 4);
Label jmp = new Label();
mv.visitVarInsn(ALOAD, 4);
mv.visitJumpInsn(IFNONNULL, jmp);
mv.visitInsn(ACONST_NULL);
Label jmp2 = new Label();
mv.visitJumpInsn(GOTO, jmp2);
mv.visitLabel(jmp);
mv.visitVarInsn(ALOAD, 4);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
mv.visitLabel(jmp2);
} else {
assert debug("<<<DYNAMIC TYPING BYPASS>>>");
assert debug("<<<OPT. JUSTIFICATION " + parameterTypes[i] + "=" + preConvArgs[i].getClass() + ">>>");
assert debug("CHECKCAST " + getInternalName(parameterTypes[i]));
mv.visitTypeInsn(CHECKCAST, getInternalName(parameterTypes[i]));
}
}
if (m.isVarArgs() && (es == null || es.length == (parameterTypes.length - 1))) {
// The last parameter is a vararg and there is no value, create an empty array array
createArray(getBaseComponentType(parameterTypes[parameterTypes.length - 1]), 0);
}
if ((m.getModifiers() & STATIC) != 0) {
assert debug("INVOKESTATIC: " + m.getName());
mv.visitMethodInsn(INVOKESTATIC, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
} else {
if (declaringClass.isInterface()) {
assert debug("INVOKEINTERFACE: " + getInternalName(declaringClass) + "." + m.getName());
mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
} else {
assert debug("INVOKEVIRTUAL: " + getInternalName(declaringClass) + "." + m.getName());
mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
}
}
returnType = m.getReturnType();
stacksize++;
}
Object o = m.invoke(ctx, normalizeArgsForVarArgs(parameterTypes, args, m.isVarArgs()));
if (hasNullMethodHandler()) {
writeOutNullHandler(m, 1);
if (o == null)
o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
}
currType = toNonPrimitiveType(m.getReturnType());
return o;
}
}
Aggregations