Re: Re: Re: Re: Analyzer does not use stack map frames
Eric Bruneton <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
07/11/2010 04:27, Marcin Rzeźnicki wrote: > I managed to add proper stack map handling to Analyzer - unfortunately > it is not doable via extending this class - mainly because analyze > method constructs Frame array which holds deduced frames so one cannot I just added an empty 'init' method in Analyzer which should allow you to put your code in a sub class of Analyzer (see attached 'Test' class) Eric
Test.java
(text/plain, 6.1 KB)
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2005 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.objectweb.asm.tree.analysis;
import java.util.List;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodNode;
public class Test extends Analyzer {
private Interpreter interpreter;
private int stackMapTop;
public Test(Interpreter interpreter) {
super(interpreter);
this.interpreter = interpreter;
}
protected void init(String owner, MethodNode m) throws AnalyzerException {
stackMapTop = Type.getArgumentsAndReturnSizes(m.desc) >> 2;
if ((m.access & ACC_STATIC) != 0) {
stackMapTop -= 1;
}
int n = m.instructions.size();
InsnList insns = m.instructions;
Frame current = getFrames()[0];
// addition: iterate through all instructions and set frames for all
// stack map frames (and for neighbour labels if there are any)
Frame stackmapFrame = current;
for (int ic = 0; ic < n; ic++) {
final AbstractInsnNode insn = insns.get(ic);
if (insn.getType() == AbstractInsnNode.FRAME) {
stackmapFrame = newFrame((FrameNode) insn, stackmapFrame);
getFrames()[ic] = stackmapFrame;
int j = 1;
AbstractInsnNode prevInsn = insn.getPrevious();
while (prevInsn != null && prevInsn.getOpcode() == -1) {
prevInsn = prevInsn.getPrevious();
getFrames()[ic - j] = stackmapFrame;
j += 1;
}
}
}
}
private Frame newFrame(FrameNode node, Frame previousFrame)
throws AnalyzerException
{
final Frame result = newFrame(previousFrame);
switch (node.type) {
case F_APPEND:
setFrameLocals(result, node.local);
result.clearStack();
break;
case F_CHOP:
int newStackMapTop = stackMapTop - node.local.size();
for (int i = newStackMapTop; i < stackMapTop; i++) {
result.setLocal(i, interpreter.newValue(null));
}
stackMapTop = newStackMapTop;
result.clearStack();
break;
case F_FULL:
stackMapTop = 0;
setFrameLocals(result, node.local);
int maxLocals = result.getLocals();
for (int i = stackMapTop; i < maxLocals; i++) {
result.setLocal(i, interpreter.newValue(null));
}
List<Object> stack = node.stack;
int nStack = stack.size();
for (int i = 0; i < nStack; i++) {
result.push(interpreter.newValue(getTypeFromFrameOpcode(stack.get(i))));
}
break;
case F_SAME:
result.clearStack();
break;
case F_SAME1:
result.clearStack();
result.push(interpreter.newValue(getTypeFromFrameOpcode(node.stack.get(0))));
break;
default:
throw new AnalyzerException(node, "Expanded frames not allowed");
}
return result;
}
private void setFrameLocals(final Frame frame, List<Object> locals) {
int nLocals = locals.size();
for (int i = 0; i < nLocals; i++) {
Value newValue = interpreter.newValue(getTypeFromFrameOpcode(locals.get(i)));
frame.setLocal(stackMapTop, newValue);
if (newValue.getSize() == 2) {
frame.setLocal(stackMapTop + 1, interpreter.newValue(null));
stackMapTop += 2;
} else {
stackMapTop += 1;
}
}
}
private static Type getTypeFromFrameOpcode(Object opcode) {
if (opcode instanceof String) {
return Type.getObjectType((String) opcode);
}
if (opcode == INTEGER) {
return Type.INT_TYPE;
}
if (opcode == FLOAT) {
return Type.FLOAT_TYPE;
}
if (opcode == LONG) {
return Type.LONG_TYPE;
}
if (opcode == DOUBLE) {
return Type.DOUBLE_TYPE;
}
if (opcode == NULL) {
return Type.VOID_TYPE;
}
return null;
}
}
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws