List of usage examples for org.objectweb.asm MethodVisitor visitVarInsn
public void visitVarInsn(final int opcode, final int var)
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); }