blob: 68ed29dfa855fca9f5cfc9aa88c6d71976901d86 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Dynamic Runtime Environment"
*
* Copyright 2009, 2014 Oliver Frank and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0 *
* 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.transformer.names.ConstantMembers;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
/**
* Create the code for the dispatch from a base class to the teams
* in the method callAllBindings. <br/> <br/>
* The code was generated as follows: <br/>
* <code>
* switch (boundMethodId) { // this was generated in CreateSwitchAdapter <br/>
* ... <br/>
* case (boundMethodId): <br/>
* Teams[] teams = TeamManager.getTeams(joinpointId) <br/>
* if (teams == null) { <br/>
* break; <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 CreateDispatchCodeInCallAllBindingsAdapter extends
AbstractCreateDispatchCodeAdapter {
private int joinpointId;
private int boundMethodId;
public CreateDispatchCodeInCallAllBindingsAdapter(int joinpointId,
int boundMethodId) {
super(false, 3); // 'this' plus two args (int, Object[])
this.joinpointId = joinpointId;
this.boundMethodId = boundMethodId;
}
@Override
public boolean transform() {
MethodNode callAllBindings = getMethod(ConstantMembers.callAllBindingsClient);
InsnList instructions = getDispatchCode(callAllBindings, joinpointId, -1); // dynamically use iload_0 instead of constant
addNewLabelToSwitch(callAllBindings.instructions, instructions, boundMethodId);
addLocals(callAllBindings);
callAllBindings.maxStack = getMaxStack();
callAllBindings.maxLocals = getMaxLocals();
return true;
}
@Override
protected InsnList getBoxedArguments(Type[] args) {
InsnList instructions = new InsnList();
instructions.add(new VarInsnNode(Opcodes.ALOAD, 2));
return instructions;
}
}