Example usage for org.objectweb.asm MethodVisitor visitInsn

List of usage examples for org.objectweb.asm MethodVisitor visitInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitInsn.

Prototype

public void visitInsn(final int opcode) 

Source Link

Document

Visits a zero operand instruction.

Usage

From source file:com.sixrr.metrics.profile.instanceHolder.MetricInstanceHolder.java

License:Apache License

private void loadMetricsFromProviders() {
    for (MetricProvider provider : MetricProvider.EXTENSION_POINT_NAME.getExtensions()) {
        final List<Class<? extends Metric>> classesForProvider = provider.getMetricClasses();

        for (Class<? extends Metric> aClass : classesForProvider) {
            try {
                myMetricInstances.put(aClass.getName(), aClass.newInstance());
            } catch (InstantiationException e) {
                MetricInstanceHolder.LOGGER.error(e);
            } catch (IllegalAccessException e) {
                MetricInstanceHolder.LOGGER.error(e);
            }/*from w  w w  .ja v  a 2  s  . c  o m*/
        }
    }

    for (Metric metric : Metric.EP_NAME.getExtensions()) {
        myMetricInstances.put(metric.getClass().getName(), metric);
    }

    // add some magic
    // in Profiles it stored by ClassName. Line Of code is can be handle without new metrics, need only extends  LinesOfCodeProjectMetric with
    // new name
    for (LineOfCodeFileTypeProviderEP ep : LineOfCodeFileTypeProviderEP.EP_NAME.getExtensions()) {
        FileType fileTypeByFileName = FileTypeRegistry.getInstance().findFileTypeByName(ep.fileType);

        if (fileTypeByFileName == null) {
            LOGGER.error("File type is unknown: " + ep.fileType);
            fileTypeByFileName = PlainTextFileType.INSTANCE;
        }
        String lineOfCodeClass = Type.getInternalName(LinesOfCodeProjectMetric.class);
        String className = lineOfCodeClass + "$" + ep.fileType;

        ClassWriter writer = new ClassWriter(Opcodes.F_FULL);
        writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, className, null, lineOfCodeClass, null);

        String desc = Type.getConstructorDescriptor(LinesOfCodeProjectMetric.class.getConstructors()[0]);
        MethodVisitor methodVisitor = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, null, null);

        methodVisitor.visitMaxs(2, 2);
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, lineOfCodeClass, "<init>", desc);
        methodVisitor.visitInsn(Opcodes.RETURN);
        methodVisitor.visitEnd();
        writer.visitEnd();

        Class<?> aClass = defineClass(className.replace("/", "."), writer.toByteArray());

        try {
            myMetricInstances.put(aClass.getName(),
                    (Metric) aClass.getConstructors()[0].newInstance(fileTypeByFileName));
        } catch (InstantiationException e) {
            LOGGER.error(e);
        } catch (IllegalAccessException e) {
            LOGGER.error(e);
        } catch (InvocationTargetException e) {
            LOGGER.error(e);
        }
    }
}

From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.SingleInsn.java

License:Open Source License

public void toAsm(MethodVisitor mv) {
    mv.visitInsn(opcode);
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * @param nm/*  www . j a  v  a 2 s. com*/
 * @param lsargs
 * @return
 */

public static void popAll(MethodVisitor mv, int onStack) {
    if (onStack == 0)
        return;
    for (; onStack > 1; onStack -= 2) {
        mv.visitInsn(POP2);
    }
    if (onStack == 1) {
        mv.visitInsn(POP);
    }
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * //  ww w  . ja  v a  2s .c om
 * Deals with overloading and narrowed signatures in the mapping
 * from Fortress methods to Java methods.
 * 
 * The problem comes, e.g., if
 * trait T 
 *   m(T):T
 * end
 * 
 * object O extends T
 *   m(T):O
 * end
 * 
 * In the translation to Java, O's m has a different return type from T's m,
 * thus it has a different signature, thus it does not properly override it
 * in the generated bytecodes.  This has to be detected, and a forwarding 
 * method for O.(T):T has to be created so that calls to T.m(T):T will
 * arrive at O.(T):O.
 * 
 * There are variants of this problem created when T defines a non-abstract
 * m(T), and O defines m(O) -- in that case, there needs to be O.m(x:T) that
 * performs the overloading.
 * 
 *   if (x instanceof O)
 *   then O.m((O)x)
 *   else T.m(x)
 *   Note that because the overloading is only valid in the case
 *   that T defined a method with a body, T.m(x) is expressed as
 *   T$defaultTraitMethods(self, x).
 * 
 * 
 * @param superInterfaces
 * @param includeCurrent
 * @return 
 */

private Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> dumpOverloadedMethodChaining(
        String[] superInterfaces, boolean includeCurrent) {
    Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> overloadedMethods = new HashMap<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>>();

    /*
     * If the number of supertraits is 0, there is nothing to override.
     */
    if (superInterfaces.length < 1)
        return overloadedMethods;

    TraitType currentTraitObjectType = STypesUtil.declToTraitTypeEnhanced(currentTraitObjectDecl);
    // TraitType currentTraitObjectType = STypesUtil.declToTraitType(currentTraitObjectDecl);
    List<TraitTypeWhere> extendsClause = NodeUtil.getExtendsClause(currentTraitObjectDecl);

    OverloadingOracle oa = new OverloadingOracle(typeAnalyzer);

    /*
     * properlyInheritedMethods is supposed to return methods that are
     * (potentially) inherited by this trait.  The declaration from the
     * most specific trait declaring a given method signature should be
     * what is returned; HOWEVER, there is a bug, in that return types
     * are apparently ignored, so two methods with same domain but different
     * return types will only result in a single method.  This can cause
     * a problem in the case that a method is available from parent and
     * from great-grandparent, AND if the parent-inheritance is not first
     * position (otherwise, a default implementation appears from the
     * parent, though this might not be the correct one).
     * 
     * Note that extends clauses should be minimal by this point, or at
     * least as-if minimal; we don't want to be dealing with duplicated
     * methods that would not trigger overriding by the meet rule (if the
     * extends clause is minimal, and a method is defined twice in the
     * extends clause, then it needs to be disambiguated in this type).
     */
    if (DEBUG_OVERLOADED_METHOD_CHAINING)
        System.err.println("Considering overloads for " + currentTraitObjectType + ", extended="
                + Useful.listTranslatedInDelimiters("[", extendsClause, "]", ",", TTWtoString));

    Relation<IdOrOpOrAnonymousName, scala.Tuple3<Functional, StaticTypeReplacer, TraitType>> toConsider = STypesUtil
            .properlyInheritedMethodsNotIdenticallyCovered(currentTraitObjectType.getName(), typeAnalyzer);

    MultiMap<IdOrOpOrAnonymousName, scala.Tuple3<Functional, StaticTypeReplacer, TraitType>> toConsiderFixed = new MultiMap<IdOrOpOrAnonymousName, scala.Tuple3<Functional, StaticTypeReplacer, TraitType>>();

    for (edu.rice.cs.plt.tuple.Pair<IdOrOpOrAnonymousName, scala.Tuple3<Functional, StaticTypeReplacer, TraitType>> assoc : toConsider) {
        IdOrOpOrAnonymousName n = assoc.first();
        scala.Tuple3<Functional, StaticTypeReplacer, TraitType> tup = assoc.second();

        Functional fnl = tup._1();
        StaticTypeReplacer inst = tup._2();
        TraitType tupTrait = tup._3();

        IdOrOpOrAnonymousName nn = inst.replaceIn(n);

        toConsiderFixed.putItem(nn, tup);

    }

    if (DEBUG_OVERLOADED_METHOD_CHAINING) {
        System.err.println("properlyInheritedMethods  (orig)=" + toConsider);
        System.err.println("properlyInheritedMethods (fixed)=" + toConsiderFixed);
    }

    TraitIndex ti = (TraitIndex) typeAnalyzer.traits().typeCons(currentTraitObjectType.getName()).unwrap();

    // This is used to fix the type annotation in type_info; it lacks
    // constraints on static parameters.
    StaticTypeReplacer local_inst = new StaticTypeReplacer(ti.staticParameters(),
            STypesUtil.staticParamsToArgsEnhanced(ti.staticParameters()));

    MultiMap<IdOrOpOrAnonymousName, Functional> nameToFSets = new MultiMap<IdOrOpOrAnonymousName, Functional>();

    // Sort defined methods into map from single names to sets of defs
    for (Map.Entry<Id, FieldGetterMethod> ent : ti.getters().entrySet()) {
        nameToFSets.putItem(ent.getKey(), ent.getValue());
    }
    for (Map.Entry<Id, FieldSetterMethod> ent : ti.setters().entrySet()) {
        nameToFSets.putItem(ent.getKey(), ent.getValue());
    }
    /*
     *  There's a glitch here, with the names of functional methods,
     *  vs their names as implemented methods.  Static analyzer works with
     *  names-as-written; code generation wishes to mangle them.
     */
    for (edu.rice.cs.plt.tuple.Pair<IdOrOpOrAnonymousName, FunctionalMethod> ent : ti.functionalMethods()) {
        nameToFSets.putItem(ent.first(), ent.second());
    }
    for (edu.rice.cs.plt.tuple.Pair<IdOrOpOrAnonymousName, DeclaredMethod> ent : ti.dottedMethods()) {
        nameToFSets.putItem(ent.first(), ent.second());
    }

    /*
     * The subtype-defined methods can overlap in several ways.
     * Classified by D->R (Domain, Range), the following relationships are
     * possible:
     * 
     * EQ -> EQ means Java dispatch works. (shadowed)
     * 
     * EQ -> LT means that the name is wrong;
     *          the (Java) EQ->EQ method must be included.
     *          (EQ->EQ cannot exist in (Fortress) subtype)
     *          
     * LT -> EQ means that there is an overloading.
     *          (EQ -> LT cannot exist in (Fortress) subtype; EQ->EQ can)
     *          
     * LT -> LT means that there is an overloading.
     *          EQ -> LT or EQ -> EQ can exist in subtype;
     *          LT -> EQ can exist in super, if it does,
     *          then it is covered in a diff relationship by EQ -> LT above.
     *          
     * EX -> ... means there is an excluding overloading
     *          
     * 
     * There may also be overloadings present in
     * the methods defined by this trait or object.
     * 
     * Forwarded methods are those that are in EQ -> LT relationship
     * with some super method.
     * 
     * Overload sets contain all methods in the subtype plus all the 
     * unshadowed, unforwarded methods from super.
     * 
     * As overloads, these are similar to function overloads, except that
     * the parameters come in 1-n instead of 0-(n-1), and the invocation
     * varies -- supertype invocation dispatches to the default-methods
     * class, subtype invocation goes, where? (to the static, if subtype
     * is a trait, otherwise, we need to dance the name out of the way).
     * 
     */

    for (Map.Entry<IdOrOpOrAnonymousName, Set<Functional>> ent : nameToFSets.entrySet()) {
        IdOrOpOrAnonymousName name = ent.getKey();
        Set<Functional> funcs = ent.getValue();

        // initial set of potential overloads is this trait/object's methods
        Set<Functional> perhapsOverloaded = new HashSet<Functional>(funcs);

        for (scala.Tuple3<Functional, StaticTypeReplacer, TraitType> overridden : toConsiderFixed
                .getEmptyIfMissing(name)) {
            // toConsider.matchFirst(name)) {
            Functional super_func = overridden._1();
            StaticTypeReplacer super_inst = overridden._2();

            if (super_func instanceof ParametricOperator) {
                // TODO -- substitute and compare, I think.
                continue;
            }

            TraitType traitDeclaringMethod = overridden._3();
            if (typeAnalyzer.equiv(traitDeclaringMethod, currentTraitObjectType))
                continue;

            boolean shadowed = false; // EQ -> EQ seen
            boolean narrowed = false; // EQ -> LT seen
            Functional narrowed_func = null;

            Type raw_super_ret = oa.getRangeType(super_func);

            int super_self_index = NodeUtil.selfParameterIndex(super_func.parameters());
            Type raw_super_noself_domain = oa.getNoSelfDomainType(super_func);
            Type super_noself_domain_possibly_no_params = super_inst
                    .replaceInEverything(raw_super_noself_domain);
            List<StaticParam> better_super_params = new ArrayList<StaticParam>();

            /*
             * Combine all the static params for super, preferring the definitions from the
             * subtype when names match (those may be narrower).
             */
            for (StaticParam bsp : super_noself_domain_possibly_no_params.getInfo().getStaticParams()) {
                boolean use_bsp = true;
                for (StaticParam sp : currentTraitObjectDecl.getHeader().getStaticParams()) {
                    if (sp.getName().equals(bsp.getName())) {
                        better_super_params.add(sp);
                        use_bsp = false;
                        break;
                    }
                }
                if (use_bsp)
                    better_super_params.add(bsp);
            }
            for (StaticParam sp : currentTraitObjectDecl.getHeader().getStaticParams()) {
                boolean use_sp = true;
                for (StaticParam bsp : super_noself_domain_possibly_no_params.getInfo().getStaticParams()) {
                    if (sp.getName().equals(bsp.getName())) {
                        use_sp = false;
                        break;
                    }
                }
                if (use_sp)
                    better_super_params.add(sp);
            }

            Type super_noself_domain = STypesUtil.insertStaticParams(
                    STypesUtil.clearStaticParams(super_noself_domain_possibly_no_params), better_super_params);

            Type pre_super_ret = super_inst.replaceInEverything(raw_super_ret);

            Type super_ret = STypesUtil.insertStaticParams(STypesUtil.clearStaticParams(pre_super_ret),
                    better_super_params);
            //          super_noself_domain_possibly_no_params.getInfo().getStaticParams().isEmpty() ?
            //          STypesUtil.insertStaticParams(super_noself_domain_possibly_no_params,     // Aha!  GLS 6/12/12
            //                    currentTraitObjectDecl.getHeader().getStaticParams()) :
            //          super_noself_domain_possibly_no_params;

            for (Functional func : funcs) {
                Type ret = local_inst.replaceInEverything(oa.getRangeType(func));
                int self_index = NodeUtil.selfParameterIndex(func.parameters());
                if (self_index != super_self_index) {
                    /*
                     * Not sure we see this ever; it is a bit of a mistake,
                     * and will require further tinkering when we sort out
                     * the overloads.  We DON'T want to attempt a type
                     * comparison of dissimilar-selfed functions.
                     */
                    continue;
                }

                /*
                 * See above comment -- I think this is the wrong instantiater,
                 * but it is not far wrong.
                 */
                Type raw_noself_domain = oa.getNoSelfDomainType(func);
                Type noself_domain = local_inst.replaceInEverything(raw_noself_domain);

                // Classify potential override

                /*
                 * Funny business with "self_index" --
                 *   the overloading oracle / type analyzer believes that
                 *   subtype_SELF more specific than supertype_SELF.
                 *   
                 *   This is not what we want for purposes of spotting
                 *   shadowing and collisions.
                 *  
                 */
                if (DEBUG_OVERLOADED_METHOD_CHAINING && name.toString().contains("seq")) {
                    System.out.println("******* " + noself_domain.toStringReadable() + " { "
                            + noself_domain.getInfo().getStaticParams() + " } " + "\nvs super "
                            + super_noself_domain.toStringReadable() + " { "
                            + super_noself_domain.getInfo().getStaticParams() + " }");
                    System.out.println("** raw super is " + raw_super_noself_domain.toStringReadable() + " { "
                            + raw_super_noself_domain.getInfo().getStaticParams() + " }");

                    System.out.println(
                            "******* " + ret.toStringReadable() + " { " + ret.getInfo().getStaticParams()
                                    + " } " + "\nvs super " + super_ret.toStringReadable() + " { "
                                    + super_ret.getInfo().getStaticParams() + " }");
                    System.out.println("** raw super is " + raw_super_ret.toStringReadable() + " { "
                            + raw_super_ret.getInfo().getStaticParams() + " }");
                    // super_noself_domain_possibly_no_params
                    System.out.println("** super pnp is "
                            + super_noself_domain_possibly_no_params.toStringReadable() + " { "
                            + super_noself_domain_possibly_no_params.getInfo().getStaticParams() + " }");
                    System.out.println("** replacer is " + super_inst);
                    System.out.println("** better super params is { " + better_super_params + " }");
                    boolean d_a_le_b = oa.lteq(noself_domain, super_noself_domain);
                    boolean d_b_le_a = oa.lteq(super_noself_domain, noself_domain);
                    boolean r_a_le_b = oa.lteq(ret, super_ret);
                    boolean r_b_le_a = oa.lteq(super_ret, ret);
                    System.err.println(
                            "" + func + " ?? " + super_func + " " + d_a_le_b + d_b_le_a + r_a_le_b + r_b_le_a);
                    System.out.println("**** END");
                }
                boolean d_a_le_b = oa.lteq(noself_domain, super_noself_domain);
                boolean d_b_le_a = oa.lteq(super_noself_domain, noself_domain);

                boolean r_a_le_b = oa.lteq(ret, super_ret);
                boolean r_b_le_a = oa.lteq(super_ret, ret);

                if (DEBUG_OVERLOADED_METHOD_CHAINING) {
                    System.err.println(
                            "" + func + " ?? " + super_func + " " + d_a_le_b + d_b_le_a + r_a_le_b + r_b_le_a);
                }

                boolean schema_narrowed = false;
                if (func.staticParameters().size() > 0) {
                    int selfIndex = ((HasSelfType) super_func).selfPosition();
                    String from_name = genericMethodName(super_func, selfIndex);
                    String to_name = genericMethodName(func, selfIndex);
                    schema_narrowed = !from_name.equals(to_name);
                }

                if (d_a_le_b && d_b_le_a) {
                    // equal domains
                    if (r_a_le_b) { // sub is LE
                        if (r_b_le_a) {
                            // eq
                            // note that GENERIC methods all have same Java return type,
                            // hence "equal".
                            if (schema_narrowed) {
                                narrowed = true; // could "continue" here
                                narrowed_func = func;
                                if (DEBUG_OVERLOADED_METHOD_CHAINING)
                                    System.err.println("  " + func + " schema-narrows " + super_func);
                            } else {
                                shadowed = true; // could "continue" here
                                if (DEBUG_OVERLOADED_METHOD_CHAINING)
                                    System.err.println("  " + func + " shadows " + super_func);
                            }

                        } else {
                            // lt
                            narrowed = true;
                            narrowed_func = func;
                            if (DEBUG_OVERLOADED_METHOD_CHAINING)
                                System.err.println("  " + func + " narrows " + super_func);

                        }
                    }
                }
            }

            if (shadowed)
                continue;
            if (narrowed) {
                //          System.out.println("generateForwardingFor:");
                //          System.out.println("  super_func = " + super_func);
                //          System.out.println("  narrowed_func = " + narrowed_func);
                //          System.out.println("  super_inst = " + super_inst);
                //          System.out.println("  currentTraitObjectType = " + currentTraitObjectType);
                if (narrowed_func.staticParameters().size() > 0) {
                    if (DEBUG_OVERLOADED_METHOD_CHAINING)
                        System.err.println("Generic narrowing, " + narrowed_func + " narrows " + super_func);
                    int selfIndex = ((HasSelfType) super_func).selfPosition();
                    String from_name = genericMethodName(super_func, selfIndex);
                    String to_name = genericMethodName(narrowed_func, selfIndex);
                    String sig = genericMethodClosureFinderSig;
                    int arity = 3; // Magic number, number of parameters to generic method closure finder
                    // TODO This could be bogus, but for now, let's try it.
                    String receiverClass = NamingCzar.jvmTypeDescAsTrait(currentTraitObjectType,
                            component.getName());

                    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, from_name, sig, null, null);
                    mv.visitCode();

                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitVarInsn(LLOAD, 1);
                    mv.visitVarInsn(ALOAD, 3);
                    mv.visitMethodInsn(inATrait ? INVOKEINTERFACE : INVOKEVIRTUAL, receiverClass, to_name,
                            genericMethodClosureFinderSig);

                    mv.visitInsn(ARETURN);
                    mv.visitMaxs(1, 1);
                    mv.visitEnd();

                } else {
                    generateForwardingFor(super_func, narrowed_func, false, super_inst, currentTraitObjectType,
                            currentTraitObjectType, true); // swapped
                }
                continue;
            }
            perhapsOverloaded.add((Functional) (((HasSelfType) super_func)
                    .instantiateTraitStaticParameters(ti.staticParameters(), super_inst))); // GLS 3/12/2012
        }

        // need to refine the overloaded methods check because of exclusion
        MultiMap<Integer, Functional> partitionedByArgCount = partitionByMethodArgCount(oa, perhapsOverloaded);

        if (partitionedByArgCount.size() > 0) {

            overloadedMethods.put(name, partitionedByArgCount);
            if (DEBUG_OVERLOADED_METHOD_CHAINING)
                System.err.println(" Method " + name + " has overloads " + perhapsOverloaded);
        }
        // TODO now emit necessary overloads, if any.

    }
    return overloadedMethods;
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * Generates the method that is called to find the closure for a generic method.
 * The method name is some minor frob on the Fortress method name, but it needs
 * the schema to help avoid overloading conflicts on the name.
 * //from   www.j a  va 2 s.c o m
 *  <pre>
 *  private static BAlongTree sampleLookupTable = new BAlongTree();
 *  public Object sampleLookup(long hashcode, String signature) {
 *  Object o = sampleLookupTable.get(hashcode);
 *  if (o == null) 
 *     o = findGenericMethodClosure(hashcode,
 *                                  sampleLookupTable,
 *                                  "template_class_name",
 *                                  signature);
 *  return o;
 *  }
 *  </pre>
 * @param method_name - may be mangled to avoid a name clash
 * @param table_name - always the unmangled version of the method_name
 * @param template_class_name
 * @param savedInATrait 
 */
public void generateGenericMethodClosureFinder(String method_name, final String table_name,
        String template_class_name, final String class_file, boolean savedInATrait) {

    initializedStaticFields_TO.add(new InitializedStaticField() {

        @Override
        public void forClinit(MethodVisitor my_mv) {
            my_mv.visitTypeInsn(NEW, Naming.CACHE_TABLE_TYPE);
            my_mv.visitInsn(DUP);
            my_mv.visitMethodInsn(INVOKESPECIAL, Naming.CACHE_TABLE_TYPE, "<init>", "()V");
            my_mv.visitFieldInsn(PUTSTATIC, class_file, table_name,
                    Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
        }

        @Override
        public String asmName() {
            return table_name;
        }

        @Override
        public String asmSignature() {
            return Naming.internalToDesc(Naming.CACHE_TABLE_TYPE);
        }

    });

    int hashOff = savedInATrait ? 0 : 1;
    int stringOff = hashOff + 2;
    int tmpOff = stringOff + 1;

    int access = savedInATrait ? ACC_PUBLIC + ACC_STATIC : ACC_PUBLIC;
    if (savedInATrait)
        method_name = method_name + Naming.GENERIC_METHOD_FINDER_SUFFIX_IN_TRAIT;

    List<StaticParam> to_sparams = this.currentTraitObjectDecl.getHeader().getStaticParams();

    CodeGenMethodVisitor mv = cw.visitCGMethod(access, method_name, genericMethodClosureFinderSig, null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    //mv.visitLineNumber(1331, l0);
    mv.visitFieldInsn(GETSTATIC, class_file, table_name, Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
    mv.visitVarInsn(LLOAD, hashOff);
    mv.visitMethodInsn(INVOKEVIRTUAL, Naming.CACHE_TABLE_TYPE, "get", "(J)Ljava/lang/Object;");
    mv.visitVarInsn(ASTORE, tmpOff);
    Label l1 = new Label();
    mv.visitLabel(l1);
    //mv.visitLineNumber(1332, l1);
    mv.visitVarInsn(ALOAD, tmpOff);
    Label l2 = new Label();
    mv.visitJumpInsn(IFNONNULL, l2);
    Label l3 = new Label();
    mv.visitLabel(l3);
    //mv.visitLineNumber(1333, l3);
    mv.visitVarInsn(LLOAD, hashOff);
    mv.visitFieldInsn(GETSTATIC, class_file, table_name, Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
    mv.visitLdcInsn(template_class_name);
    mv.visitVarInsn(ALOAD, stringOff);
    // if in a generic trait/object, need to call different method and include one more parameter.
    if (to_sparams.size() == 0) {
        mv.visitMethodInsn(INVOKESTATIC, Naming.RT_HELPERS, "findGenericMethodClosure",
                "(JLcom/sun/fortress/runtimeSystem/BAlongTree;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
    } else {
        // Need to use the substitute-at-load string operation.
        String string_sargs = NamingCzar.genericDecoration(null, to_sparams, null, thisApi());
        String loadString = Naming.opForString(Naming.stringMethod, string_sargs);
        mv.visitMethodInsn(INVOKESTATIC, Naming.magicInterpClass, loadString, "()Ljava/lang/String;");
        mv.visitMethodInsn(INVOKESTATIC, Naming.RT_HELPERS, "findGenericMethodClosure",
                "(JLcom/sun/fortress/runtimeSystem/BAlongTree;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
    }
    mv.visitVarInsn(ASTORE, tmpOff);
    mv.visitLabel(l2);
    //mv.visitLineNumber(1335, l2);
    mv.visitFrame(F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null);
    mv.visitVarInsn(ALOAD, tmpOff);
    mv.visitInsn(ARETURN);
    Label l4 = new Label();
    mv.visitLabel(l4);

    if (!savedInATrait)
        mv.visitLocalVariable("this", Naming.internalToDesc(class_file), null, l0, l4, 0);

    mv.visitLocalVariable("hashcode", "J", null, l0, l4, hashOff);
    mv.visitLocalVariable("signature", "Ljava/lang/String;", null, l0, l4, stringOff);
    mv.visitLocalVariable("o", "Ljava/lang/Object;", null, l1, l4, tmpOff);
    // 6,6 if in a generic trait.
    //        mv.visitMaxs(5, 5);
    mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
    mv.visitEnd();
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * Newspeak for forwarding; the old forwarding method code is too atrocious for words.
 * //w w w . ja  v a2s  .com
 * @param cw
 * @param generated_method_name
 * @param generated_method_sig
 * @param invoked_method_trait_object
 * @param invoked_method_name
 * @param self_index
 * @param n_params_including_self
 * @param is_a_trait
 */
static void functionalForwardingMethod(ClassWriter cw, String generated_method_name,
        String generated_method_sig, String invoked_method_trait_object, String invoked_method_name,
        int self_index, int n_params_including_self, boolean is_a_trait) {
    String invoked_method_sig = Naming.removeNthSigParameter(generated_method_sig, self_index);
    String self_sig = Naming.nthSigParameter(generated_method_sig, self_index);
    self_sig.substring(1, self_sig.length() - 1); // Strip off L;

    String ret_type = Naming.sigRet(invoked_method_sig);

    MethodVisitor mv = cw.visitMethod(ACC_STATIC + ACC_PUBLIC, generated_method_name, generated_method_sig,
            null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, self_index);
    // If the self_sig does not match the type that we are about to invoke,
    // cast it.
    if (!self_sig.equals(invoked_method_trait_object)) {
        InstantiatingClassloader.generalizedCastTo(mv, invoked_method_trait_object);
    }
    // push parameters, except for self
    for (int i = 0; i < n_params_including_self; i++)
        if (i != self_index) {
            mv.visitVarInsn(ALOAD, i);
        }

    // invoke
    mv.visitMethodInsn(is_a_trait ? INVOKEINTERFACE : INVOKEVIRTUAL, invoked_method_trait_object,
            invoked_method_name, invoked_method_sig);

    // This will need to generalize for covariant types, I expect
    if (ret_type.startsWith(Naming.TUPLE_OX) || ret_type.startsWith(Naming.ARROW_OX)) {
        InstantiatingClassloader.generalizedCastTo(mv, ret_type);
    }
    mv.visitInsn(ARETURN);

    mv.visitMaxs(2, 3);
    mv.visitEnd();

}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

public void forObjectDeclPrePass(ObjectDecl x) {
    debug("Begin forObjectDeclPrePass for ", x);
    TraitTypeHeader header = x.getHeader();
    List<TraitTypeWhere> extendsC = header.getExtendsClause();

    boolean canCompile =
            // x.getParams().isNone() &&             // no parameters
            // header.getStaticParams().isEmpty() && // no static parameter
            header.getWhereClause().isNone() && // no where clause
                    header.getThrowsClause().isNone() && // no throws clause
                    header.getContract().isNone() && // no contract
                    //            header.getDecls().isEmpty() &&        // no members
                    Modifiers.ObjectMod.containsAll(header.getMods())
    // ( extendsC.size() <= 1 ); // 0 or 1 super trait
    ;/*from  w  w w . j a va  2 s  . c om*/

    if (!canCompile)
        throw sayWhat(x);

    // Map<String, String> xlation = new HashMap<String, String>();
    List<String> splist = new ArrayList<String>();
    final List<StaticParam> original_static_params = header.getStaticParams();
    Option<List<Param>> original_params = NodeUtil.getParams(x);

    Naming.XlationData xldata = xlationData(Naming.OBJECT_GENERIC_TAG);

    boolean savedInAnObject = inAnObject;
    inAnObject = true;
    Id classId = NodeUtil.getName(x);

    final ClassNameBundle cnb = new_ClassNameBundle(classId, original_static_params, xldata);

    String erasedSuperI = (EMIT_ERASED_GENERICS && cnb.isGeneric) ? cnb.stemClassName : "";
    String[] superInterfaces = NamingCzar.extendsClauseToInterfaces(extendsC, component.getName(),
            erasedSuperI);

    if (EMIT_ERASED_GENERICS && cnb.isGeneric) {
        emitErasedClassFor(cnb, (TraitObjectDecl) x);
    }

    String abstractSuperclass;
    if (superInterfaces.length > 0) {
        abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard;
    } else {
        abstractSuperclass = NamingCzar.internalObject;
    }

    traitOrObjectName = cnb.className;
    debug("forObjectDeclPrePass ", x, " classFile = ", traitOrObjectName);

    boolean isSingletonObject = NodeUtil.getParams(x).isNone();
    List<Param> params;
    if (!isSingletonObject) {
        params = NodeUtil.getParams(x).unwrap(); //TUPLE CONSTRUCTOR PROBLEM
        String init_sig = NamingCzar.jvmSignatureFor(params, "V", thisApi());

        // Generate the factory method
        String sig = NamingCzar.jvmSignatureFor(params, cnb.classDesc, thisApi());

        String mname;

        CodeGen cg = this;
        String PCN = null;
        String PCNOuter = null;

        ArrayList<InitializedStaticField> isf_list = new ArrayList<InitializedStaticField>();

        if (cnb.isGeneric) {
            ArrowType at = FnNameInfo.typeAndParamsToArrow(NodeUtil.getSpan(x),
                    NodeFactory.makeTraitType(classId, STypesUtil.staticParamsToArgs(original_static_params)),
                    original_params.unwrap());
            String generic_arrow_type = NamingCzar.jvmTypeDesc(at, thisApi(), false);

            PCNforClosure pair = nonCollidingClosureName(generic_arrow_type, Naming.NO_SELF,
                    (IdOrOp) x.getHeader().getName(), original_static_params, this.packageAndClassName);

            PCN = pair.PCN;
            PCNOuter = pair.PCNOuter;
            xldata = pair.xldata;

            cg = new CodeGen(this);
            cg.cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw);

            // This creates the closure bits
            // The name is disambiguated by the class in which it appears.
            mname = InstantiatingClassloader.closureClassPrefix(PCN, cg.cw, PCN, sig, null, isf_list);
        } else {
            mname = nonCollidingSingleName(x.getHeader().getName(), sig, "");
        }

        CodeGenClassWriter cw = cg.cw;
        CodeGenMethodVisitor mv = cw.visitCGMethod(ACC_STATIC + ACC_PUBLIC, mname, sig, null, null);

        mv.visitTypeInsn(NEW, cnb.className);
        mv.visitInsn(DUP);

        // iterate, pushing parameters, beginning at zero.
        // TODO actually handle N>0 parameters.

        int numParams = params.size();
        //if only a single parameter which is a tuple, signature will give them individually
        if (numParams == 1 && (params.get(0).getIdType().unwrap() instanceof TupleType)) {
            Param p0 = params.get(0);
            TupleType tuple_type = ((TupleType) p0.getIdType().unwrap());
            List<Type> tuple_types = tuple_type.getElements();
            numParams = tuple_types.size();
        }
        for (int stack_offset = 0; stack_offset < numParams; stack_offset++) {
            // when we unbox, this will be type-dependent
            mv.visitVarInsn(ALOAD, stack_offset);
        }

        mv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", init_sig);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
        mv.visitEnd();

        if (cnb.isGeneric) {
            InstantiatingClassloader.optionalStaticsAndClassInitForTO(isf_list, cg.cw);

            cg.cw.dumpClass(PCNOuter, xldata);
        }

    } else { // singleton
        params = Collections.<Param>emptyList();
    }

    CodeGenClassWriter prev = cw;

    /* Yuck, ought to allocate a new codegen here. */

    initializedStaticFields_TO = new ArrayList<InitializedStaticField>();

    cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw);
    cw.visitSource(NodeUtil.getSpan(x).begin.getFileName(), null);

    // Until we resolve the directory hierarchy problem.
    //            cw.visit( V1_5, ACC_PUBLIC + ACC_SUPER+ ACC_FINAL,
    //                      classFile, null, NamingCzar.internalObject, new String[] { parent });
    cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, cnb.className,
            null, abstractSuperclass, superInterfaces);

    if (isSingletonObject) {

        initializedStaticFields_TO.add(new InitializedStaticField() {

            @Override
            public void forClinit(MethodVisitor imv) {
                imv.visitTypeInsn(NEW, cnb.className);
                imv.visitInsn(DUP);
                imv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", Naming.voidToVoid);
                imv.visitFieldInsn(PUTSTATIC, cnb.className, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc);
            }

            @Override
            public String asmName() {
                return NamingCzar.SINGLETON_FIELD_NAME;
            }

            @Override
            public String asmSignature() {
                return cnb.classDesc;
            }

        });

        /* Used to pass splist to the static-parametered form
         * but it was always empty.  Tests work like that.
         * Bit of a WTF, keep an eye on this.
         * Repurpose splist (non-null) for the computation and
         * caching of RTTI, which also goes in a static.
         */
        addStaticVar(new VarCodeGen.StaticBinding(classId, NodeFactory.makeTraitType(classId),
                cnb.stemClassName, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc));

        //            // Singleton; generate field in class to hold sole instance.
        //            cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
        //                          NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc,
        //                          null /* for non-generic */, null /* instance has no value */);
    }

    currentTraitObjectDecl = x;
    //create CodeGen for init method
    // has different set of parameter variables in scope
    CodeGen initCodeGen = initializeInitMethod(params);

    initCodeGen.initializedInstanceFields_O = new ArrayList<InitializedInstanceField>();
    //        List<Binding> fieldsForEnv = new ArrayList<Binding>();
    initCodeGen.instanceFields = new InstanceFields();

    BATree<String, VarCodeGen> savedLexEnv = lexEnv.copy();

    // for each parameter
    // 1) add field to the class
    // 2) add field along with initializer to list of instance fields to put in the constructor
    // 3) add parameter to local scope of init method
    // 4) add field to scope for use in methods
    for (int i = 0; i < params.size(); i++) {
        Param p = params.get(i);

        String paramName = p.getName().getText();
        Type paramType = (Type) p.getIdType().unwrap();
        String typeDesc = NamingCzar.jvmBoxedTypeDesc(paramType, thisApi());
        Id id = NodeFactory.makeId(NodeUtil.getSpan(p.getName()), paramName);
        VarCodeGen vcg = new VarCodeGen.FieldVar(id, paramType, cnb.className, paramName, typeDesc);

        //1) add field to class
        cw.visitField(ACC_PUBLIC + ACC_FINAL, paramName, typeDesc, null /* for non-generic */,
                null /* instance has no value */);

        //2) add field with initializer as a refernce to the parameter
        initCodeGen.instanceFields.put(vcg, ExprFactory.makeVarRef(id));

        //3) add param to scope for init method only
        initCodeGen.addStaticVar(new VarCodeGen.ParamVar(id, paramType, initCodeGen));

        //4) add field to scope for method codegen
        addStaticVar(vcg);
    }

    // find declared fields in the list of decls and
    // 1) add field to the class
    // 2) add field along with initializer to list of instance fields to put in the constructor
    // 3) add field to scope for use in methods
    for (Decl d : header.getDecls()) {
        if (d instanceof VarDecl) {
            // TODO need to spot for "final" fields.  Right now we assume mutable, not final.
            final VarDecl vd = (VarDecl) d;
            final CodeGen cg = this;
            int numDecls = vd.getLhs().size();
            for (int i = 0; i < numDecls; i++) {
                LValue l = vd.getLhs().get(i);
                String fieldName = l.getName().getText();
                Type fieldType = (Type) l.getIdType().unwrap();
                String typeDesc = NamingCzar.jvmBoxedTypeDesc(fieldType, thisApi());
                Id id = NodeFactory.makeId(NodeUtil.getSpan(l.getName()), fieldName);
                VarCodeGen fieldVcg = new VarCodeGen.MutableFieldVar(id, fieldType, cnb.className, fieldName,
                        typeDesc);

                //1) add field to class
                cw.visitField(ACC_PUBLIC, fieldName, typeDesc, null /* for non-generic */,
                        null /* instance has no value */);

                //2) set up initializer
                if (vd.getInit().isNone())
                    sayWhat(vd, "no initializer for declared field(s)");
                Expr init = vd.getInit().unwrap();

                if (numDecls != 1 && init instanceof TupleExpr) {
                    List<Expr> tupleExprs = ((TupleExpr) init).getExprs();
                    if (tupleExprs.size() != numDecls)
                        sayWhat(vd, "incorrect initialization for declared fields tuple");
                    init = tupleExprs.get(i);
                }
                initCodeGen.instanceFields.put(fieldVcg, init);

                //3) add field to scope for method codegen
                addStaticVar(fieldVcg);
            }
        }
    }

    debug("Dump overloaded method chaining for ", x);
    Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> overloads = dumpOverloadedMethodChaining(
            superInterfaces, false);
    if (OVERLOADED_METHODS)
        typeLevelOverloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), overloads, typeAnalyzer, cw,
                this, new OverloadSet.TraitOrObjectFactory(Opcodes.INVOKEVIRTUAL, cnb, this));
    debug("End of dump overloaded method chaining for ", x);

    debug("Process declarations for ", x);
    for (Decl d : header.getDecls()) {
        // This does not work yet.
        d.accept(this);
    }
    debug("End of processing declarations for ", x);

    initCodeGen.instanceInitForObject(abstractSuperclass);

    debug("Dump method chaining for ", x);
    dumpMethodChaining(superInterfaces, false);
    // dumpErasedMethodChaining(superInterfaces, false);
    debug("End of dump method chaining for ", x);

    /* RTTI stuff */
    mv = cw.visitCGMethod(Opcodes.ACC_PUBLIC, // acccess
            Naming.RTTI_GETTER, // name
            Naming.STATIC_PARAMETER_GETTER_SIG, // sig
            null, // generics sig?
            null); // exceptions
    mv.visitCode();
    mv.visitFieldInsn(GETSTATIC, cnb.className, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC);

    areturnEpilogue();

    emitRttiField(cnb);
    /* end RTTI stuff */

    lexEnv = savedLexEnv;

    optionalStaticsAndClassInitForTO(classId, cnb, isSingletonObject);

    if (cnb.isGeneric) {
        cw.dumpClass(cnb.fileName, xldata.setTraitObjectTag(Naming.OBJECT_GENERIC_TAG));
    } else {
        cw.dumpClass(cnb.className);
    }
    cw = prev;
    initializedInstanceFields_O = null;
    initializedStaticFields_TO = null;
    currentTraitObjectDecl = null;

    traitOrObjectName = null;

    inAnObject = savedInAnObject;

    // Needed (above) to embed a reference to the Rtti information for this type.
    RttiClassAndInterface(x, cnb, xldata);
    debug("End forObjectDeclPrePass for ", x);
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * @param classId/*from  www .java2 s.c om*/
 * @param cnb
 * @param isSingletonObject
 */
private void optionalStaticsAndClassInitForTO(Id classId, ClassNameBundle cnb, boolean isSingletonObject) {
    if (initializedStaticFields_TO.size() == 0 && !isSingletonObject)
        return;

    MethodVisitor imv = cw.visitMethod(ACC_STATIC, "<clinit>", Naming.voidToVoid, null, null);
    for (InitializedStaticField isf : initializedStaticFields_TO) {
        isf.forClinit(imv);
        cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, isf.asmName(), isf.asmSignature(),
                null /* for non-generic */, null /* instance has no value */);
        // DRC-WIP
    }

    imv.visitInsn(RETURN);
    imv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
    imv.visitEnd();
}

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

/**
 * Generate the default constructor for this class.
 * This constructors calls the method setToplevel().
 * If this environment is not a top-level environment, then a default
 * constructor does not need to be created.  (ASM will generate a
 * default constructor)./*from   www  .  jav  a 2 s.c o  m*/
 */
private static void writeMethodInit(ClassWriter cw, String className) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getType(BaseEnv.class).getInternalName(), "<init>", "()V");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, "setTopLevel", "()V");
    mv.visitInsn(Opcodes.RETURN);
    // See comment above on ClassWriter.COMPUTE_FRAMES
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

/**
 * Implementing "static reflection" for the method getFooRaw so the
 * interpreter uses a switch instruction for ***GetRaw
 * based on the hash values of String names in this namespace.
 *///from w ww .ja v a2s .c om
private static void writeMethodGetRaw(ClassWriter cw, String className, String methodName,
        EnvironmentClass environmentClass, EnvSymbolNames symbolNames) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName,
            "(Ljava/lang/String;)" + environmentClass.descriptor(), null, null);
    mv.visitCode();

    Label beginFunction = new Label();
    mv.visitLabel(beginFunction);

    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I");
    mv.visitVarInsn(Opcodes.ISTORE, 2);
    Label beginLoop = new Label();
    mv.visitLabel(beginLoop);

    Relation<String, Integer> hashCodeRelation = symbolNames.makeHashCodeRelation(environmentClass);
    ArrayList<Integer> sortedCodes = new ArrayList<Integer>(hashCodeRelation.secondSet());
    Collections.sort(sortedCodes);
    Label returnNull = new Label();

    getRawHelper(mv, className, hashCodeRelation, environmentClass, sortedCodes, returnNull);

    mv.visitLabel(returnNull);
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitInsn(Opcodes.ARETURN);

    Label endFunction = new Label();
    mv.visitLabel(endFunction);
    mv.visitLocalVariable("this", Naming.internalToDesc(className), null, beginFunction, endFunction, 0);
    mv.visitLocalVariable("queryString", "Ljava/lang/String;", null, beginFunction, endFunction, 1);
    mv.visitLocalVariable("queryHashCode", "I", null, beginLoop, endFunction, 2);
    // See comment above on ClassWriter.COMPUTE_FRAMES
    mv.visitMaxs(2, 3);
    mv.visitEnd();
}