Java tutorial
/********************************************************************** * This file is part of "Object Teams Dynamic Runtime Environment" * * Copyright 2009, 2014 Oliver Frank and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Please visit http://www.eclipse.org/objectteams for updates and contact. * * Contributors: * Oliver Frank - Initial API and implementation * Stephan Herrmann - Initial API and implementation **********************************************************************/ package org.eclipse.objectteams.otredyn.bytecode.asm; import org.eclipse.objectteams.otredyn.bytecode.Method; import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; /** * Create the code for the dispatch from a base class to the teams * in the original method. <br/> <br/> * The code was generated as follows: <br/> * <code> * Teams[] teams = TeamManager.getTeams(joinpointId) <br/> * if (teams == null) { <br/> * Object args[] = {arg1, ..., argn}; <br/> * return callOrig(boundMethodId, args); <br/> * } <br/> * <br/> * Team t = teams[0]; <br/> * int[] callinIds = TeamManager.getCallinIds(joinpointId); <br/> * Object[] args = {arg1, ... , argn}; * return team._OT$callAllBindings(this, teams, 0, callinIds, boundMethodId, args); * } <br/> * </code> * @author Oliver Frank */ public class CreateDispatchCodeInOrgMethodAdapter extends AbstractCreateDispatchCodeAdapter { private Method method; private int joinPointId; private int boundMethodId; public CreateDispatchCodeInOrgMethodAdapter(Method method, int joinPointId, int boundMethodId) { super(true); this.method = method; this.joinPointId = joinPointId; this.boundMethodId = boundMethodId; } @Override public boolean transform() { MethodNode orgMethod = getMethod(method); if ((orgMethod.access & Opcodes.ACC_ABSTRACT) != 0) return false; orgMethod.instructions.clear(); orgMethod.instructions.add(getDispatchCode(orgMethod, joinPointId, boundMethodId)); orgMethod.maxStack = getMaxStack(); orgMethod.maxLocals = getMaxLocals(); return true; } @Override protected InsnList getBoxedArguments(Type[] args) { return getBoxingInstructions(args, true); } @Override protected InsnList createInstructionsToCheackTeams(MethodNode method) { InsnList instructions = new InsnList(); instructions.add(new InsnNode(Opcodes.DUP)); LabelNode label = new LabelNode(); //if (teams == null) { instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, label)); instructions.add(new InsnNode(Opcodes.POP)); //put the boundMethodId on the stack instructions.add(createLoadIntConstant(boundMethodId)); Type[] args = Type.getArgumentTypes(method.desc); // box the arguments instructions.add(getBoxingInstructions(args, (method.access & Opcodes.ACC_STATIC) != 0)); //callOrigStatic(boundMethodId, args); instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, name, ConstantMembers.callOrigStatic.getName(), ConstantMembers.callOrigStatic.getSignature())); Type returnType = Type.getReturnType(method.desc); instructions.add(getUnboxingInstructionsForReturnValue(returnType)); instructions.add(label); return instructions; } }