public void visitFunctionDeclaration(FunctionDeclarationContext function) { symbolTable.newScope(); Function f = buildFunction(function); returnType = f.getReturnValueType(); f.getArguments().stream().forEach(symbolTable::defineVariable); Type[] argTypes = f.getArguments() .stream() .flatMap(variable -> Stream.of(variable.getValueType().toAsmType())) .toArray(Type[]::new); String descriptor = Type.getMethodDescriptor(f.getReturnValueType().toAsmType(), argTypes); if ("main".equals(f.getName())) { if (!f.getArguments().isEmpty()) { throw new GenerationException("Main function must have zero arguments"); } descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String[].class)); } method = writer.visitMethod(ACC_PUBLIC | ACC_STATIC, f.getName(), descriptor, null, null); BlockContext block = function.functionBody().block(); visitBlock(block); checkReturn(block); method.visitMaxs(0, 0); method.visitEnd(); symbolTable.dropScope(); }
private void writeSetter(ClassVisitor visitor, Type generatedType, ModelProperty<?> property) { WeaklyTypeReferencingMethod<?, Void> weakSetter = property.getSetter(); // There is no setter for this property if (weakSetter == null) { return; } String propertyName = property.getName(); Class<?> propertyClass = property.getType().getConcreteClass(); Type propertyType = Type.getType(propertyClass); Label calledOutsideOfConstructor = new Label(); Method setter = weakSetter.getMethod(); // the regular typed setter String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, propertyType); MethodVisitor methodVisitor = declareMethod( visitor, setter.getName(), methodDescriptor, AsmClassGeneratorUtils.signature(setter)); putCanCallSettersFieldValueOnStack(methodVisitor, generatedType); jumpToLabelIfStackEvaluatesToTrue(methodVisitor, calledOutsideOfConstructor); throwExceptionBecauseCalledOnItself(methodVisitor); methodVisitor.visitLabel(calledOutsideOfConstructor); putStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, propertyName); putFirstMethodArgumentOnStack(methodVisitor, propertyType); if (propertyClass.isPrimitive()) { boxType(methodVisitor, propertyClass); } invokeStateSetMethod(methodVisitor); finishVisitingMethod(methodVisitor); }
/** * Translates a simple type descriptor, specifically. Only translates names in the descriptor, if * they are represented by class mirrors. */ protected String translateDescriptor(final String descriptor) { Type type = Type.getType(descriptor); type = getMirrorType(type); return type.getDescriptor(); }
public TouchMethodVisitor( String owner, MethodNode methodNode, MethodVisitor methodVisitor, Set<Label> jumpLabels, Map<Label, Integer> lineLabels, Map<Label, SwitchHolder> switchLabels) { super(Opcodes.ASM5, methodVisitor); _owner = owner; _jumpLabels = jumpLabels; _lineLabels = lineLabels; _switchLabels = switchLabels; int variableCount = 0; if ((Opcodes.ACC_STATIC & methodNode.access) == 0) { variableCount++; } for (Type type : Type.getArgumentTypes(methodNode.desc)) { variableCount += type.getSize(); } _variableCount = variableCount; }
protected void injectGetByIndex( ClassWriter classWriter, String targetClassName, List<Field> fields) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())}); Boxer boxer = new Boxer(methodVisitor); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ILOAD, 2); int maxStack = 6; Label[] labels = new Label[fields.size()]; Label errorLabel = new Label(); for (int i = 0; i < fields.size(); i++) { labels[i] = new Label(); } methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels); if (!fields.isEmpty()) { maxStack--; for (int i = 0; i < fields.size(); i++) { Field field = fields.get(i); Class<?> type = field.getType(); String fieldDescriptor = Type.getDescriptor(type); methodVisitor.visitLabel(labels[i]); if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null); else methodVisitor.visitFrame(F_SAME, 0, null, 0, null); if (isPublic(field)) { methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, targetClassName); methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor); boxer.box(Type.getType(type)); } else { injectReflectiveGetter(methodVisitor); } methodVisitor.visitInsn(ARETURN); } methodVisitor.visitLabel(errorLabel); methodVisitor.visitFrame(F_SAME, 0, null, 0, null); } injectException(methodVisitor, IllegalAccessException.class); methodVisitor.visitMaxs(maxStack, 3); methodVisitor.visitEnd(); }
/** Returns the reference/primitive class to store the */ private static String findReferenceDesc(String desc) { Type type = Type.getType(desc); switch (type.getSort()) { case Type.ARRAY: return "Lorg/multiverse/transactional/refs/BasicRef;"; case Type.BOOLEAN: return "Lorg/multiverse/transactional/refs/BooleanRef;"; case Type.BYTE: return "Lorg/multiverse/transactional/refs/ByteRef;"; case Type.CHAR: return "Lorg/multiverse/transactional/refs/CharRef;"; case Type.DOUBLE: return "Lorg/multiverse/transactional/refs/DoubleRef;"; case Type.FLOAT: return "Lorg/multiverse/transactional/refs/FloatRef;"; case Type.INT: return "Lorg/multiverse/transactional/refs/IntRef;"; case Type.LONG: return "Lorg/multiverse/transactional/refs/LongRef;"; case Type.SHORT: return "Lorg/multiverse/transactional/refs/ShortRef;"; case Type.OBJECT: return "Lorg/multiverse/transactional/refs/BasicRef;"; default: throw new IllegalStateException("Unhandeled sort: " + type.getSort()); } }
public Param(String typeDesc) { loadInstruction = Opcodes.ALOAD; storeInstruction = Opcodes.ASTORE; typeId = TypeIdMap.TYPEID_OBJECT; t = Type.getType(typeDesc); assert t.getDescriptor().equals(typeDesc); }
/** * Creates a new local variable of the given type. * * @param type the type of the local variable to be created. * @return the identifier of the newly created local variable. */ public int newLocal(final Type type) { Object t; switch (type.getSort()) { case Type.BOOLEAN: case Type.CHAR: case Type.BYTE: case Type.SHORT: case Type.INT: t = Opcodes.INTEGER; break; case Type.FLOAT: t = Opcodes.FLOAT; break; case Type.LONG: t = Opcodes.LONG; break; case Type.DOUBLE: t = Opcodes.DOUBLE; break; case Type.ARRAY: t = type.getDescriptor(); break; // case Type.OBJECT: default: t = type.getInternalName(); break; } int local = newLocalMapping(type); setLocalType(local, type); setFrameLocal(local, t); return local; }
private static byte[] visitEnd() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, RubyIDClassName, null, "java/lang/Object", null); Method staticBlock = Method.getMethod("void <clinit> ()V"); GeneratorAdapter staticBlockMg = new GeneratorAdapter(Opcodes.ACC_STATIC, staticBlock, null, null, cw); for (Map.Entry<String, String> e : idMap.entrySet()) { cw.visitField( Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, e.getValue(), Types.RUBY_ID_TYPE.getDescriptor(), null, null); staticBlockMg.push(e.getKey()); staticBlockMg.invokeStatic( Type.getType(RubyID.class), Method.getMethod("com.xruby.runtime.lang.RubyID intern(String)")); staticBlockMg.putStatic( Type.getType("L" + RubyIDClassName + ";"), e.getValue(), Types.RUBY_ID_TYPE); } staticBlockMg.returnValue(); staticBlockMg.endMethod(); cw.visitEnd(); return cw.toByteArray(); }
@Override public final void visit(String name, Object value) { if (value == null) throw new Error(); Type type; if (value.getClass().equals(String.class)) { type = Type.getType(String.class); } else if (value.getClass().equals(Boolean.class)) { type = Type.BOOLEAN_TYPE; } else if (value.getClass().equals(Integer.class)) { type = Type.INT_TYPE; } else if (value.getClass().equals(Long.class)) { type = Type.LONG_TYPE; } else if (value.getClass().equals(Type.class)) { type = Type.getType(Class.class); } else { throw new Error("name=" + name + " value=" + value + " " + value.getClass()); } if (name == null) { anon(type, value); } else { add(name, new AnnotationValue(type, value)); } }
private void generateAccessor( ClassWriter cw, Class<?> parentType, String internalName, Property<Class<?>, Method> property) { Method accessor = property.getAccessor(); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, accessor.getName(), Type.getMethodDescriptor(accessor), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, internalName, property.getName(), Type.getDescriptor(property.getLeastSpecificType())); if (!property.isLeastSpecificType()) { mv.visitTypeInsn(CHECKCAST, Type.getInternalName(property.getType())); } mv.visitInsn(Type.getType(property.getType()).getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); }
private static AbstractInsnNode getDefault(Type type) { if (type.equals(Type.BOOLEAN_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.BYTE_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.CHAR_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.DOUBLE_TYPE)) { return new LdcInsnNode(0.0); } else if (type.equals(Type.FLOAT_TYPE)) { return new LdcInsnNode(0.0F); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.LONG_TYPE)) { return new LdcInsnNode(0L); } else if (type.equals(Type.SHORT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.VOID_TYPE)) { return new LabelNode(); } else { return new InsnNode(Opcodes.ACONST_NULL); } }
public JvmObjectConstant(Object constant) { super( constant == null ? null : constant instanceof Integer ? Type.INT_TYPE : constant instanceof Long ? Type.LONG_TYPE : constant instanceof Float ? Type.FLOAT_TYPE : constant instanceof Double ? Type.DOUBLE_TYPE : constant instanceof Byte ? Type.BYTE_TYPE : constant instanceof Short ? Type.SHORT_TYPE : constant instanceof Character ? Type.CHAR_TYPE : constant instanceof String ? Type.getType(String.class) : constant instanceof Type ? Type.getType(Class.class) : null); this.constant = constant; }
public void handleMethod( String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation, List<Value> values) { System.err.println( "Sample annotated method : classname=" + className + " methodName=" + methodName + " access=" + access + " desc=" + desc + " signature=" + signature); org.objectweb.asm.Type retType = org.objectweb.asm.Type.getReturnType(desc); System.err.println("REturn type = " + retType); org.objectweb.asm.Type[] params = org.objectweb.asm.Type.getArgumentTypes(desc); if (params == null) System.err.println("No params"); else System.err.println(params.length + " params"); if (exceptions == null) System.err.println("No exceptions"); else System.err.println(exceptions.length + " exceptions"); assertEquals("org.eclipse.jetty.annotations.ClassA", className); assertTrue(methods.contains(methodName)); assertEquals("org.eclipse.jetty.annotations.Sample", annotation); }
private void addMethodDesc(final String desc) { addType(Type.getReturnType(desc)); Type[] types = Type.getArgumentTypes(desc); for (int i = 0; i < types.length; i++) { addType(types[i]); } }
private int firePeacefulRegenEventAndStoreEventBefore( MethodNode method, AbstractInsnNode injectPoint, LabelNode endLabel) { // create variable LabelNode peacefulRegenEventStart = new LabelNode(); LocalVariableNode peacefulRegenEvent = new LocalVariableNode( "peacefulRegenEvent", Type.getDescriptor(HealthRegenEvent.PeacefulRegen.class), null, peacefulRegenEventStart, endLabel, method.maxLocals); method.maxLocals += 1; method.localVariables.add(peacefulRegenEvent); InsnList toInject = new InsnList(); // HealthRegenEvent.PeacefulRegen peacefulRegenEvent = Hooks.firePeacefulRegenEvent(this); toInject.add(new VarInsnNode(ALOAD, 0)); toInject.add( new MethodInsnNode( INVOKESTATIC, Type.getInternalName(Hooks.class), "firePeacefulRegenEvent", "(Lnet/minecraft/entity/player/EntityPlayer;)Lsqueek/applecore/api/hunger/HealthRegenEvent$PeacefulRegen;", false)); toInject.add(new VarInsnNode(ASTORE, peacefulRegenEvent.index)); toInject.add(peacefulRegenEventStart); method.instructions.insertBefore(injectPoint, toInject); return peacefulRegenEvent.index; }
private void writeConstructor( ClassVisitor visitor, Type generatedType, Type superclassType, StructSchema<?> delegateSchema) { String constructorDescriptor; Type delegateType; if (delegateSchema == null) { delegateType = null; constructorDescriptor = NO_DELEGATE_CONSTRUCTOR_DESCRIPTOR; } else { delegateType = Type.getType(delegateSchema.getType().getConcreteClass()); constructorDescriptor = Type.getMethodDescriptor( Type.VOID_TYPE, MODEL_ELEMENT_STATE_TYPE, TYPE_CONVERTER_TYPE, delegateType); } MethodVisitor constructorVisitor = declareMethod(visitor, CONSTRUCTOR_NAME, constructorDescriptor, CONCRETE_SIGNATURE); invokeSuperConstructor(constructorVisitor, superclassType); assignStateField(constructorVisitor, generatedType); assignTypeConverterField(constructorVisitor, generatedType); if (delegateType != null) { assignDelegateField(constructorVisitor, generatedType, delegateType); } setCanCallSettersField(constructorVisitor, generatedType, true); finishVisitingMethod(constructorVisitor); }
/** * Find the annotations to add to the given method and remove from the set of things to annotate * * @param className name of class we're adding annotation to * @param methodName name of method we're adding annotation to * @param methodDesc descriptor of method * @return set on annotations to add to method or null if none */ static Set<Class<? extends Annotation>> findAnnotationsForMethod( String className, String methodName, String methodDesc) { for (AnnotatedElement elem : thingsToAnnotate.keySet()) { if (elem instanceof Method) { Method m = (Method) elem; if (m.getDeclaringClass().getName().equals(className) && m.getName().equals(methodName) && Type.getMethodDescriptor(m).equals(methodDesc)) { annotatedElements.add(m); return thingsToAnnotate.get(m); } } else if (elem instanceof Constructor) { Constructor m = (Constructor) elem; if (m.getDeclaringClass().getName().equals(className) && Type.getConstructorDescriptor(m).equals(methodDesc)) { annotatedElements.add(m); return thingsToAnnotate.get(m); } } } ElementTriple triple = new ElementTriple(className, methodName, methodDesc); Set<Class<? extends Annotation>> set = thingsToAnnotate2.get(triple); if (set != null) { annotatedElements2.add(triple); } return set; }
public static Class<?> getClassForType(Type type) { checkArgNotNull(type, "type"); switch (type.getSort()) { case Type.BOOLEAN: return boolean.class; case Type.BYTE: return byte.class; case Type.CHAR: return char.class; case Type.DOUBLE: return double.class; case Type.FLOAT: return float.class; case Type.INT: return int.class; case Type.LONG: return long.class; case Type.SHORT: return short.class; case Type.VOID: return void.class; case Type.OBJECT: case Type.ARRAY: return getClassForInternalName(type.getInternalName()); } throw new IllegalStateException(); // should be unreachable }
public DirectedGraph<Node, Edge> convert() { DirectedGraph<Node, Edge> graph = new SimpleDirectedGraph<Node, Edge>(Edge.factory); // Add vertices for (Type t : hierarchy) graph.addVertex(Node.get(t)); // Add edges for (Type t : hierarchy) { for (Type i : hierarchy.getInterfaces(t)) { graph.addVertex(Node.get(i)); graph.addEdge(Node.get(t), Node.get(i)); } Type sc = hierarchy.getSuperclass(t); if (sc == null) { assert t.equals(OBJECT) : t; continue; } graph.addVertex(Node.get(sc)); graph.addEdge(Node.get(t), Node.get(sc)); } // Check for cycles if (new CycleDetector<Node, Edge>(graph).detectCycles()) throw new CyclicHierarchyException(graph.toString()); return graph; }
private ClassBuilderImpl(Class<T> type) { this.type = type; visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS); typeName = type.getName() + "_Decorated"; generatedType = Type.getType("L" + typeName.replaceAll("\\.", "/") + ";"); superclassType = Type.getType(type); }
@Override public final void visitEnum(String name, String desc, String value) { if (name == null) { anon(Type.getType(desc), value); return; } add(name, new AnnotationValue(Type.getType(desc), value)); }
private Set<String> mapGetDescriptor(AnnotationWithClassValuesDescriptor annotation) { Set<String> result = new HashSet<String>(); for (Object o : annotation.properties.getArrayValues("annotations")) { Type type = (Type) o; result.add(type.getDescriptor()); } return result; }
public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions) { Type[] args = Type.getArgumentTypes(desc); Type returnType = Type.getReturnType(desc); int startParameter = getStartParameterIndex(name); MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions); return new MyMethodAdapter(this, v, args, returnType, access, startParameter, name); }
private void boxType(MethodVisitor methodVisitor, Class<?> primitiveType) { Class<?> boxedType = BOXED_TYPES.get(primitiveType); methodVisitor.visitMethodInsn( INVOKESTATIC, Type.getInternalName(boxedType), "valueOf", "(" + Type.getDescriptor(primitiveType) + ")" + Type.getDescriptor(boxedType), false); }
private void invokeSuperConstructor(MethodVisitor constructorVisitor, Type superclassType) { putThisOnStack(constructorVisitor); constructorVisitor.visitMethodInsn( INVOKESPECIAL, superclassType.getInternalName(), CONSTRUCTOR_NAME, Type.getMethodDescriptor(Type.VOID_TYPE), false); }
private void assignStateField(MethodVisitor constructorVisitor, Type generatedType) { putThisOnStack(constructorVisitor); putFirstMethodArgumentOnStack(constructorVisitor); constructorVisitor.visitFieldInsn( PUTFIELD, generatedType.getInternalName(), STATE_FIELD_NAME, MODEL_ELEMENT_STATE_TYPE.getDescriptor()); }
private void assignTypeConverterField(MethodVisitor constructorVisitor, Type generatedType) { putThisOnStack(constructorVisitor); putSecondMethodArgumentOnStack(constructorVisitor); constructorVisitor.visitFieldInsn( PUTFIELD, generatedType.getInternalName(), TYPE_CONVERTER_FIELD_NAME, TYPE_CONVERTER_TYPE.getDescriptor()); }
@Override public void visitLdcInsn(Object cst) { if (cst instanceof Type) { Type type = (Type) cst; AsmClass usedClass = asmClassProvider.getClass(type.getInternalName(), DETAIL_LEVEL.NOTHING); method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber)); } emptyMethod = false; }
private static byte[] generate(String name, Class<?> type, Class<?> parameter) { name = name.replace('.', '/'); String typeName = Type.getInternalName(type); String typeDesc = Type.getDescriptor(type); String parameterName = Type.getInternalName(parameter); String parameterDesc = Type.getDescriptor(parameter); String constructSignature = '(' + parameterDesc + ')' + typeDesc; ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, BASE_CLASS, null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Class;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "<init>", "(Ljava/lang/Class;)V", false); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "construct", constructSignature, null, null); mv.visitCode(); mv.visitTypeInsn(NEW, typeName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, typeName, "<init>", '(' + parameterDesc + ")V", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "construct", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, parameterName); mv.visitMethodInsn(INVOKEVIRTUAL, name, "construct", constructSignature, false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }