use of org.springframework.cglib.core.CodeEmitter in project spring-framework by spring-projects.
the class Enhancer method emitMethods.
private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) {
CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes);
Map groups = new HashMap();
final Map indexes = new HashMap();
final Map originalModifiers = new HashMap();
final Map positions = CollectionUtils.getIndexMap(methods);
final Map declToBridge = new HashMap();
Iterator it1 = methods.iterator();
Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
while (it1.hasNext()) {
MethodInfo method = (MethodInfo) it1.next();
Method actualMethod = (it2 != null) ? (Method) it2.next() : null;
int index = filter.accept(actualMethod);
if (index >= callbackTypes.length) {
throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
}
originalModifiers.put(method, (actualMethod != null ? actualMethod.getModifiers() : method.getModifiers()));
indexes.put(method, index);
List group = (List) groups.get(generators[index]);
if (group == null) {
groups.put(generators[index], group = new ArrayList(methods.size()));
}
group.add(method);
// so that we can look up all the bridge methods in one pass for a class.
if (TypeUtils.isBridge(actualMethod.getModifiers())) {
Set bridges = (Set) declToBridge.get(actualMethod.getDeclaringClass());
if (bridges == null) {
bridges = new HashSet();
declToBridge.put(actualMethod.getDeclaringClass(), bridges);
}
bridges.add(method.getSignature());
}
}
final Map bridgeToTarget = new BridgeMethodResolver(declToBridge, getClassLoader()).resolveAll();
Set seenGen = new HashSet();
CodeEmitter se = ce.getStaticHook();
se.new_instance(THREAD_LOCAL);
se.dup();
se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
se.putfield(THREAD_CALLBACKS_FIELD);
final Object[] state = new Object[1];
CallbackGenerator.Context context = new CallbackGenerator.Context() {
public ClassLoader getClassLoader() {
return Enhancer.this.getClassLoader();
}
public int getOriginalModifiers(MethodInfo method) {
return ((Integer) originalModifiers.get(method)).intValue();
}
public int getIndex(MethodInfo method) {
return ((Integer) indexes.get(method)).intValue();
}
public void emitCallback(CodeEmitter e, int index) {
emitCurrentCallback(e, index);
}
public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer) positions.get(method)).intValue());
}
public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) {
// If this is a bridge and we know the target was called from invokespecial,
// then we need to invoke_virtual w/ the bridge target instead of doing
// a super, because super may itself be using super, which would bypass
// any proxies on the target.
Signature bridgeTarget = (Signature) bridgeToTarget.get(method.getSignature());
if (bridgeTarget != null) {
// checkcast each argument against the target's argument types
for (int i = 0; i < bridgeTarget.getArgumentTypes().length; i++) {
e.load_arg(i);
Type target = bridgeTarget.getArgumentTypes()[i];
if (!target.equals(method.getSignature().getArgumentTypes()[i])) {
e.checkcast(target);
}
}
e.invoke_virtual_this(bridgeTarget);
Type retType = method.getSignature().getReturnType();
// method.)
if (!retType.equals(bridgeTarget.getReturnType())) {
e.checkcast(retType);
}
} else {
e.load_args();
e.super_invoke(method.getSignature());
}
}
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction && !TypeUtils.isAbstract(method.getModifiers())) {
Label constructed = e.make_label();
e.load_this();
e.getfield(CONSTRUCTED_FIELD);
e.if_jump(CodeEmitter.NE, constructed);
e.load_this();
e.load_args();
e.super_invoke();
e.return_value();
e.mark(constructed);
}
return e;
}
};
for (int i = 0; i < callbackTypes.length; i++) {
CallbackGenerator gen = generators[i];
if (!seenGen.contains(gen)) {
seenGen.add(gen);
final List fmethods = (List) groups.get(gen);
if (fmethods != null) {
try {
gen.generate(ce, context, fmethods);
gen.generateStatic(se, context, fmethods);
} catch (RuntimeException x) {
throw x;
} catch (Exception x) {
throw new CodeGenerationException(x);
}
}
}
}
se.return_value();
se.end_method();
}
use of org.springframework.cglib.core.CodeEmitter in project spring-framework by spring-projects.
the class Enhancer method emitNewInstanceCallbacks.
private void emitNewInstanceCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
Type thisType = getThisType(e);
e.load_arg(0);
e.invoke_static(thisType, SET_THREAD_CALLBACKS, false);
emitCommonNewInstance(e);
}
use of org.springframework.cglib.core.CodeEmitter in project spring-framework by spring-projects.
the class Enhancer method emitDefaultConstructor.
private void emitDefaultConstructor(ClassEmitter ce) {
Constructor<Object> declaredConstructor;
try {
declaredConstructor = Object.class.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Object should have default constructor ", e);
}
MethodInfo constructor = (MethodInfo) MethodInfoTransformer.getInstance().transform(declaredConstructor);
CodeEmitter e = EmitUtils.begin_method(ce, constructor, Constants.ACC_PUBLIC);
e.load_this();
e.dup();
Signature sig = constructor.getSignature();
e.super_invoke_constructor(sig);
e.return_value();
e.end_method();
}
use of org.springframework.cglib.core.CodeEmitter in project spring-framework by spring-projects.
the class Enhancer method emitSetStaticCallbacks.
private void emitSetStaticCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC, SET_STATIC_CALLBACKS, null);
e.load_arg(0);
e.putfield(STATIC_CALLBACKS_FIELD);
e.return_value();
e.end_method();
}
use of org.springframework.cglib.core.CodeEmitter in project spring-framework by spring-projects.
the class Enhancer method emitNewInstanceMultiarg.
private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null);
final Type thisType = getThisType(e);
e.load_arg(2);
e.invoke_static(thisType, SET_THREAD_CALLBACKS, false);
e.new_instance(thisType);
e.dup();
e.load_arg(0);
EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
MethodInfo constructor = (MethodInfo) key;
Type[] types = constructor.getSignature().getArgumentTypes();
for (int i = 0; i < types.length; i++) {
e.load_arg(1);
e.push(i);
e.aaload();
e.unbox(types[i]);
}
e.invoke_constructor(thisType, constructor.getSignature());
e.goTo(end);
}
public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
}
});
e.aconst_null();
e.invoke_static(thisType, SET_THREAD_CALLBACKS, false);
e.return_value();
e.end_method();
}
Aggregations