blob: 33e963f53db367f494f941672a72fde91a6168cc [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Dynamic Runtime Environment"
*
* Copyright 2009, 2012 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.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;
import org.objectweb.asm.tree.VarInsnNode;
/**
* Initially prepares the method callAllBindings as follows: <br/><br/>
* <code>
* switch (boundMethodId) {<br/>
* default:<br/>
* break;<br/>
* }<br/>
* <br/>
* return callOrig(boundMethodId, args);<br/>
* </code>
* @author Oliver Frank
*/
public class CreateSwitchForCallAllBindingsNode extends CreateSwitchAdapter {
private Type[] args;
private LabelNode gotoLabel;
public CreateSwitchForCallAllBindingsNode() {
super(ConstantMembers.callAllBindingsClient);
}
@Override
protected void addPreSwitchInstructions(MethodNode method) {
super.addPreSwitchInstructions(method);
}
@Override
protected void addInstructionForDefaultLabel(MethodNode method) {
gotoLabel = new LabelNode();
method.instructions.add(new JumpInsnNode(Opcodes.GOTO, gotoLabel));
}
@Override
protected void addPostSwitchInstructions(MethodNode method) {
method.instructions.add(gotoLabel);
method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
args = Type.getArgumentTypes(method.desc);
int length = args.length;
for (int i = 0; i < length; i++) {
Type arg = args[i];
method.instructions.add(new VarInsnNode(arg.getOpcode(Opcodes.ILOAD), i + 1));
}
// return callOrig(boundMethodId, args);
method.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, name, ConstantMembers.callOrig.getName(), ConstantMembers.callOrig.getSignature(), false));
method.instructions.add(new InsnNode(Opcodes.ARETURN));
}
@Override
protected int getMaxStack() {
return args.length + 1;
}
}