use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class StringPropertyCodeGenerator method generateCustomSetValue.
public boolean generateCustomSetValue(final LwComponent lwComponent, final InstrumentationClassFinder.PseudoClass componentClass, final LwIntrospectedProperty property, final GeneratorAdapter generator, final int componentLocal, final String formClassName) throws IOException, ClassNotFoundException {
final InstrumentationClassFinder.PseudoClass abstractButtonClass = componentClass.getFinder().loadClass(AbstractButton.class.getName());
final InstrumentationClassFinder.PseudoClass jLabelClass = componentClass.getFinder().loadClass(JLabel.class.getName());
if ("text".equals(property.getName()) && (abstractButtonClass.isAssignableFrom(componentClass) || jLabelClass.isAssignableFrom(componentClass))) {
final StringDescriptor propertyValue = (StringDescriptor) lwComponent.getPropertyValue(property);
if (propertyValue.getValue() != null) {
final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(propertyValue.getValue());
if (textWithMnemonic.myMnemonicIndex >= 0) {
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.myText);
generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method(property.getWriteMethodName(), Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
String setMnemonicMethodName;
if (abstractButtonClass.isAssignableFrom(componentClass)) {
setMnemonicMethodName = "setMnemonic";
} else {
setMnemonicMethodName = "setDisplayedMnemonic";
}
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.getMnemonicChar());
generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method(setMnemonicMethodName, Type.VOID_TYPE, new Type[] { Type.CHAR_TYPE }));
if (myHaveSetDisplayedMnemonicIndex) {
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.myMnemonicIndex);
generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method("setDisplayedMnemonicIndex", Type.VOID_TYPE, new Type[] { Type.INT_TYPE }));
}
return true;
}
} else {
Method method;
if (abstractButtonClass.isAssignableFrom(componentClass)) {
myClassesRequiringLoadButtonText.add(formClassName);
method = myLoadButtonTextMethod;
} else {
myClassesRequiringLoadLabelText.add(formClassName);
method = myLoadLabelTextMethod;
}
generator.loadThis();
generator.loadLocal(componentLocal);
generator.push(propertyValue.getBundleName());
generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
generator.push(propertyValue.getKey());
generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
generator.invokeVirtual(Type.getType("L" + formClassName + ";"), method);
return true;
}
}
return false;
}
use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class TypeRepr method getType.
public static AbstractType getType(InternedString descr) {
final DependencyContext context = descr.getContext();
final Type t = Type.getType(descr.asString());
switch(t.getSort()) {
case Type.OBJECT:
return context.getType(new ClassType(context.get(StringUtil.replaceChar(t.getClassName(), '.', '/'))));
case Type.ARRAY:
return context.getType(new ArrayType(getType(context, t.getElementType())));
default:
return context.getType(new PrimitiveType(descr.asInt()));
}
}
use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class NegationInterpreter method createStartFrame.
final Frame<BasicValue> createStartFrame() {
Frame<BasicValue> frame = new Frame<>(methodNode.maxLocals, methodNode.maxStack);
Type returnType = Type.getReturnType(methodNode.desc);
BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
frame.setReturn(returnValue);
Type[] args = Type.getArgumentTypes(methodNode.desc);
int local = 0;
if ((methodNode.access & ACC_STATIC) == 0) {
frame.setLocal(local++, ThisValue);
}
for (int i = 0; i < args.length; i++) {
BasicValue value = new NthParamValue(args[i], i);
frame.setLocal(local++, value);
if (args[i].getSize() == 2) {
frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
}
}
while (local < methodNode.maxLocals) {
frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
}
return frame;
}
use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class InOutInterpreter method naryOperation.
@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
boolean propagate = resultOrigins[insns.indexOf(insn)];
int opCode = insn.getOpcode();
int shift = opCode == INVOKESTATIC ? 0 : 1;
switch(opCode) {
case INVOKESPECIAL:
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
if (nullAnalysis && values.get(0) instanceof ParamValue) {
deReferenced = true;
return super.naryOperation(insn, values);
}
}
if (propagate) {
switch(opCode) {
case INVOKESTATIC:
case INVOKESPECIAL:
case INVOKEVIRTUAL:
case INVOKEINTERFACE:
boolean stable = opCode == INVOKESTATIC || opCode == INVOKESPECIAL;
MethodInsnNode mNode = (MethodInsnNode) insn;
Method method = new Method(mNode.owner, mNode.name, mNode.desc);
Type retType = Type.getReturnType(mNode.desc);
boolean isRefRetType = retType.getSort() == Type.OBJECT || retType.getSort() == Type.ARRAY;
if (!Type.VOID_TYPE.equals(retType)) {
if (direction instanceof InOut) {
InOut inOut = (InOut) direction;
HashSet<Key> keys = new HashSet<>();
for (int i = shift; i < values.size(); i++) {
if (values.get(i) instanceof ParamValue) {
keys.add(new Key(method, new InOut(i - shift, inOut.inValue), stable));
}
}
if (isRefRetType) {
keys.add(new Key(method, Out, stable));
}
if (!keys.isEmpty()) {
return new CallResultValue(retType, keys);
}
} else if (isRefRetType) {
HashSet<Key> keys = new HashSet<>();
keys.add(new Key(method, Out, stable));
return new CallResultValue(retType, keys);
}
}
break;
case MULTIANEWARRAY:
return new NotNullValue(super.naryOperation(insn, values).getType());
default:
}
}
return super.naryOperation(insn, values);
}
use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class AnalyzerExt method analyze.
public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException {
if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
frames = (Frame<V>[]) new Frame<?>[0];
return frames;
}
final V refV = (V) BasicValue.REFERENCE_VALUE;
n = m.instructions.size();
insns = m.instructions;
handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
frames = (Frame<V>[]) new Frame<?>[n];
subroutines = new Subroutine[n];
queued = new boolean[n];
queue = new int[n];
top = 0;
// computes exception handlers for each instruction
for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
int begin = insns.indexOf(tcb.start);
int end = insns.indexOf(tcb.end);
for (int j = begin; j < end; ++j) {
List<TryCatchBlockNode> insnHandlers = handlers[j];
if (insnHandlers == null) {
insnHandlers = new ArrayList<>();
handlers[j] = insnHandlers;
}
insnHandlers.add(tcb);
}
}
// computes the subroutine for each instruction:
Subroutine main = new Subroutine(null, m.maxLocals, null);
List<AbstractInsnNode> subroutineCalls = new ArrayList<>();
Map<LabelNode, Subroutine> subroutineHeads = new HashMap<>();
findSubroutine(0, main, subroutineCalls);
while (!subroutineCalls.isEmpty()) {
JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
Subroutine sub = subroutineHeads.get(jsr.label);
if (sub == null) {
sub = new Subroutine(jsr.label, m.maxLocals, jsr);
subroutineHeads.put(jsr.label, sub);
findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
} else {
sub.callers.add(jsr);
}
}
for (int i = 0; i < n; ++i) {
if (subroutines[i] != null && subroutines[i].start == null) {
subroutines[i] = null;
}
}
// initializes the data structures for the control flow analysis
Frame<V> current = newFrame(m.maxLocals, m.maxStack);
Frame<V> handler = newFrame(m.maxLocals, m.maxStack);
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
Type[] args = Type.getArgumentTypes(m.desc);
int local = 0;
if ((m.access & ACC_STATIC) == 0) {
Type ctype = Type.getObjectType(owner);
current.setLocal(local++, interpreter.newValue(ctype));
}
for (int i = 0; i < args.length; ++i) {
current.setLocal(local++, interpreter.newValue(args[i]));
if (args[i].getSize() == 2) {
current.setLocal(local++, interpreter.newValue(null));
}
}
while (local < m.maxLocals) {
current.setLocal(local++, interpreter.newValue(null));
}
interpreter.init(data[0]);
merge(0, current, null);
init(owner, m);
// control flow analysis
while (top > 0) {
int insn = queue[--top];
Frame<V> f = frames[insn];
Subroutine subroutine = subroutines[insn];
queued[insn] = false;
AbstractInsnNode insnNode = null;
try {
insnNode = m.instructions.get(insn);
int insnOpcode = insnNode.getOpcode();
int insnType = insnNode.getType();
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
interpreter.init(data[insn]);
merge(insn + 1, f, subroutine);
newControlFlowEdge(insn, insn + 1);
} else {
// delta
interpreter.init(data[insn]);
current.init(f).execute(insnNode, interpreter);
subroutine = subroutine == null ? null : subroutine.copy();
if (insnNode instanceof JumpInsnNode) {
JumpInsnNode j = (JumpInsnNode) insnNode;
if (insnOpcode != GOTO && insnOpcode != JSR) {
merge(insn + 1, current, subroutine);
newControlFlowEdge(insn, insn + 1);
}
int jump = insns.indexOf(j.label);
if (insnOpcode == JSR) {
merge(jump, current, new Subroutine(j.label, m.maxLocals, j));
} else {
merge(jump, current, subroutine);
}
newControlFlowEdge(insn, jump);
} else if (insnNode instanceof LookupSwitchInsnNode) {
LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
int jump = insns.indexOf(lsi.dflt);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
for (int j = 0; j < lsi.labels.size(); ++j) {
LabelNode label = lsi.labels.get(j);
jump = insns.indexOf(label);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
}
} else if (insnNode instanceof TableSwitchInsnNode) {
TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
int jump = insns.indexOf(tsi.dflt);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
for (int j = 0; j < tsi.labels.size(); ++j) {
LabelNode label = tsi.labels.get(j);
jump = insns.indexOf(label);
merge(jump, current, subroutine);
newControlFlowEdge(insn, jump);
}
} else if (insnOpcode == RET) {
if (subroutine == null) {
throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
}
for (int i = 0; i < subroutine.callers.size(); ++i) {
JumpInsnNode caller = subroutine.callers.get(i);
int call = insns.indexOf(caller);
if (frames[call] != null) {
merge(call + 1, frames[call], current, subroutines[call], subroutine.access);
newControlFlowEdge(insn, call + 1);
}
}
} else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
if (subroutine != null) {
if (insnNode instanceof VarInsnNode) {
int var = ((VarInsnNode) insnNode).var;
subroutine.access[var] = true;
if (insnOpcode == LLOAD || insnOpcode == DLOAD || insnOpcode == LSTORE || insnOpcode == DSTORE) {
subroutine.access[var + 1] = true;
}
} else if (insnNode instanceof IincInsnNode) {
int var = ((IincInsnNode) insnNode).var;
subroutine.access[var] = true;
}
}
merge(insn + 1, current, subroutine);
newControlFlowEdge(insn, insn + 1);
}
}
List<TryCatchBlockNode> insnHandlers = handlers[insn];
if (insnHandlers != null) {
for (int i = 0; i < insnHandlers.size(); ++i) {
TryCatchBlockNode tcb = insnHandlers.get(i);
int jump = insns.indexOf(tcb.handler);
if (newControlFlowExceptionEdge(insn, tcb)) {
handler.init(f);
handler.clearStack();
handler.push(refV);
merge(jump, handler, subroutine);
}
}
}
} catch (AnalyzerException e) {
throw new AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e);
} catch (Exception e) {
throw new AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e);
}
}
return frames;
}
Aggregations