Example usage for org.objectweb.asm MethodVisitor visitVarInsn

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

Introduction

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

Prototype

public void visitVarInsn(final int opcode, final int var) 

Source Link

Document

Visits a local variable instruction.

Usage

From source file:com.peergreen.arquillian.generator.CommonClassAdapter.java

License:Open Source License

public MethodVisitor callToSuperClass() {
    MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();//from   w  ww.j a  va2 s .  com
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(superClass), "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
    return mv;
}

From source file:com.quartercode.jtimber.rh.agent.util.ASMUtils.java

License:Open Source License

/**
 * Generates the instructions to call the {@code addParent()} or {@code removeParent()} method on an object using {@code this} as the parent.
 * Note that an instanceof check is be executed beforehand in order to check whether the object is non-null and parent-aware.<br>
 * <br>//from ww  w. java2s .  co  m
 * The object the operation should be performed on needs to be the topmost value on the stack when the generated instructions are entered.
 * The rest of the stack is ignored by the generated instructions.
 * 
 * @param mv The {@link MethodVisitor} that should be used to generate the instructions.
 * @param methodName The name of the method to call ({@code "addParent"} or {@code "removeParent"}).
 */
public static void generateAddOrRemoveThisAsParent(MethodVisitor mv, String methodName) {

    // Skip the if-block if the condition below isn't true
    Label endIf = new Label();
    mv.visitInsn(DUP);
    mv.visitTypeInsn(INSTANCEOF, PARENT_AWARE_CLASS);
    mv.visitJumpInsn(IFEQ, endIf);

    /* if (object instanceof ParentAware) */
    {
        // Push a copy of the value because the parent watcher method will be invoked on it
        mv.visitInsn(DUP);

        // Push "this" because it will be used as the first argument for the following method call
        mv.visitVarInsn(ALOAD, 0);

        // Invoke the parent watcher method on the value (which implements the "ParentAware" interface) using "this" as the first argument
        mv.visitMethodInsn(INVOKEINTERFACE, PARENT_AWARE_CLASS, methodName, "(" + NODE_DESC + ")V", true);
    }

    mv.visitLabel(endIf);
}

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);
            }/*  w  w  w .  j  a  v  a 2s  .  co  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.VarInsn.java

License:Open Source License

public void toAsm(MethodVisitor mv) {
    mv.visitVarInsn(opcode, var);
}

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

License:Open Source License

/**
 * //w ww. j  ava  2 s .  c o m
 * 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

/**
 * Newspeak for forwarding; the old forwarding method code is too atrocious for words.
 * /*from  www .j a  v  a2 s . c  om*/
 * @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.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  ww w  .j av a2  s.  co  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   ww w .j av  a2s  .  co  m*/
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();
}

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

License:Open Source License

private static void getRawHelper(MethodVisitor mv, String className, Relation<String, Integer> hashCodeRelation,
        EnvironmentClass environmentClass, List<Integer> sortedCodes, Label returnNull) {
    int[] codes = new int[sortedCodes.size()];
    Label[] labels = new Label[sortedCodes.size()];
    for (int i = 0; i < codes.length; i++) {
        codes[i] = sortedCodes.get(i);//from w w  w. ja v  a2  s .c  o  m
        Label label = new Label();
        labels[i] = label;
    }
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitLookupSwitchInsn(returnNull, codes, labels);
    for (int i = 0; i < codes.length; i++) {
        mv.visitLabel(labels[i]);
        getRawBaseCase(mv, className, hashCodeRelation, environmentClass, codes[i], returnNull);
    }
}

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

License:Open Source License

private static void getRawBaseCase(MethodVisitor mv, String className,
        Relation<String, Integer> hashCodeRelation, EnvironmentClass environmentClass, int code,
        Label returnNull) {//ww w  . j av  a2s  .  c  o  m

    PredicateSet<String> strings = hashCodeRelation.matchSecond(code);
    for (String testString : strings) {
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn(testString);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
        Label afterReturn = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, afterReturn);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        String idString = testString + environmentClass.namespace();
        mv.visitFieldInsn(Opcodes.GETFIELD, className, Naming.mangleIdentifier(idString),
                environmentClass.descriptor());
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitLabel(afterReturn);
    }
    mv.visitJumpInsn(Opcodes.GOTO, returnNull);
}