List of usage examples for org.objectweb.asm Opcodes ARETURN
int ARETURN
To view the source code for org.objectweb.asm Opcodes ARETURN.
Click Source Link
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.DefUseChains.java
License:Open Source License
private static void removeUnboxedValueInsns(AbstractInterpretationValue val, ByteCodeMethodVisitor bcmv) { for (Insn i : val.getDefs()) removeInsn(bcmv, i, val, "RemovingBoxedValueDefinition"); for (Insn i : val.getUses()) { if (i.isBoxingMethod()) { removeInsn(bcmv, i, val, "RemoveBoxingMethod"); } else if (i.isUnBoxingMethod()) { removeInsn(bcmv, i, val, "UnboxingMethod"); } else if (i.isCheckCast()) { removeInsn(bcmv, i, val, "CheckCast"); // FIXME CHF } else if (i instanceof VarInsn) { VarInsn vi = (VarInsn) i;/* w w w.j a va 2 s . com*/ if (vi.opcode == Opcodes.ASTORE) { int j = bcmv.insns.indexOf(i); removeInsn(bcmv, i, val, "astoreconversion" + val.getType()); if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ32;")) bcmv.insns.add(j, new VarInsn("ISTORE", Opcodes.ISTORE, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ64;")) bcmv.insns.add(j, new VarInsn("LSTORE", Opcodes.LSTORE, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR32;")) bcmv.insns.add(j, new VarInsn("FSTORE", Opcodes.FSTORE, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR64;")) bcmv.insns.add(j, new VarInsn("DSTORE", Opcodes.DSTORE, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FBoolean;")) bcmv.insns.add(j, new VarInsn("ISTORE", Opcodes.ISTORE, val.getValueNumber(), vi.index)); else bcmv.insns.add(j, new VarInsn("ASTORE", Opcodes.ASTORE, val.getValueNumber(), vi.index)); } else if (vi.opcode == Opcodes.ALOAD) { int j = bcmv.insns.indexOf(i); removeInsn(bcmv, i, val, "Aloadconversion" + val.getType()); if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ32;")) bcmv.insns.add(j, new VarInsn("ILOAD", Opcodes.ILOAD, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ64;")) bcmv.insns.add(j, new VarInsn("LLOAD", Opcodes.LLOAD, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR32;")) bcmv.insns.add(j, new VarInsn("FLOAD", Opcodes.FLOAD, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR64;")) bcmv.insns.add(j, new VarInsn("DLOAD", Opcodes.DLOAD, val.getValueNumber(), vi.index)); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FBoolean;")) bcmv.insns.add(j, new VarInsn("ILOAD", Opcodes.ILOAD, val.getValueNumber(), vi.index)); else bcmv.insns.add(j, new VarInsn("ALOAD", Opcodes.ALOAD, val.getValueNumber(), vi.index)); } } else if (i instanceof SingleInsn) { SingleInsn si = (SingleInsn) i; if (si.opcode == Opcodes.ARETURN) { int j = bcmv.insns.indexOf(i); if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ32;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FZZ32", "make", "(I)Lcom/sun/fortress/compiler/runtimeValues/FZZ32;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FZZ64;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FZZ64", "make", "(J)Lcom/sun/fortress/compiler/runtimeValues/FZZ64;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR32;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FRR32", "make", "(F)Lcom/sun/fortress/compiler/runtimeValues/FRR32;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FRR64;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FRR64", "make", "(D)Lcom/sun/fortress/compiler/runtimeValues/FRR64;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FVoid;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FVoid", "make", "()Lcom/sun/fortress/compiler/runtimeValues/FVoid;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FBoolean;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FBoolean", "make", "(Z)Lcom/sun/fortress/compiler/runtimeValues/FBoolean;", "ReboxingReturnValue")); else if (val.getType().equals("Lcom/sun/fortress/compiler/runtimeValues/FJavaString;")) bcmv.insns.add(j, new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "com/sun/fortress/compiler/runtimeValues/FJavaString", "make", "(java.lang.String)Lcom/sun/fortress/compiler/runtimeValues/FJavaString;", "ReboxingReturnValue")); else throw new RuntimeException("Don't recognize var type " + val.getType()); } } } }
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.Inlining.java
License:Open Source License
public static List<Insn> convertInsns(MethodInsn mi, List<Insn> insns, int[] args, int _index, Label end) { List<Insn> result = new ArrayList<Insn>(); HashMap labels = new HashMap(); int index = _index; for (Insn i : insns) { if (i.isExpanded()) { MethodInsn expanded = (MethodInsn) i; // This use of end should be OK because all returns should have been removed when inlined before. // What could go wrong? result.addAll(convertInsns(expanded, expanded.inlineExpansionInsns, args, _index, end)); } else if (i instanceof SingleInsn) { SingleInsn si = (SingleInsn) i; switch (si.opcode) { case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.ARETURN: case Opcodes.RETURN: result.add(new JumpInsn("RETURN->GOTO", Opcodes.GOTO, end, newIndex(mi, index++))); break; default: result.add(i.copy(newIndex(mi, index++))); }//from w ww .ja v a 2s. c o m } else if (i instanceof VarInsn) { VarInsn vi = (VarInsn) i; switch (vi.opcode) { case Opcodes.ILOAD: case Opcodes.LLOAD: case Opcodes.FLOAD: case Opcodes.DLOAD: case Opcodes.ALOAD: case Opcodes.ISTORE: case Opcodes.LSTORE: case Opcodes.FSTORE: case Opcodes.DSTORE: case Opcodes.ASTORE: VarInsn newVarInsn = new VarInsn(vi.name, vi.opcode, args[vi.var], newIndex(mi, index++)); result.add(newVarInsn); break; default: result.add(i.copy(newIndex(mi, index++))); } } else if (i instanceof VisitMaxs) { } else if (i instanceof VisitEnd) { } else if (i instanceof VisitCode) { } else if (i instanceof VisitFrame) { } else if (i instanceof LabelInsn) { LabelInsn li = (LabelInsn) i; if (labels.containsKey(li.label)) result.add(new LabelInsn(li.name, (Label) labels.get(li.label), newIndex(mi, index++))); else { Label l = new Label(); labels.put(li.label, l); result.add(new LabelInsn(li.name, l, newIndex(mi, index++))); } } else if (i instanceof JumpInsn) { JumpInsn ji = (JumpInsn) i; if (labels.containsKey(ji.label)) result.add( new JumpInsn(ji.name, ji.opcode, (Label) labels.get(ji.label), newIndex(mi, index++))); else { Label l = new Label(); labels.put(ji.label, l); result.add(new JumpInsn(ji.name, ji.opcode, l, newIndex(mi, index++))); } } else if (i instanceof VisitLineNumberInsn) { VisitLineNumberInsn vlni = (VisitLineNumberInsn) i; if (labels.containsKey(vlni.start)) result.add(new VisitLineNumberInsn(vlni.name, vlni.line, (Label) labels.get(vlni.start), newIndex(mi, index++))); else { Label l = new Label(); labels.put(vlni.start, l); result.add(new VisitLineNumberInsn(vlni.name, vlni.line, l, newIndex(mi, index++))); } } else if (i instanceof LocalVariableInsn) { LocalVariableInsn lvi = (LocalVariableInsn) i; if (labels.containsKey(lvi.start) && labels.containsKey(lvi.end)) { result.add(new LocalVariableInsn(lvi.name, lvi._name, lvi.desc, lvi.sig, (Label) labels.get(lvi.start), (Label) labels.get(lvi.end), args[lvi._index], newIndex(mi, index++))); } else throw new RuntimeException("NYI"); } else if (i instanceof TryCatchBlock) { TryCatchBlock tcb = (TryCatchBlock) i; if (labels.containsKey(tcb.start) && labels.containsKey(tcb.end) && labels.containsKey(tcb.handler)) { result.add( new TryCatchBlock(tcb.name, (Label) labels.get(tcb.start), (Label) labels.get(tcb.end), (Label) labels.get(tcb.handler), tcb.type, newIndex(mi, index++))); } else if (!labels.containsKey(tcb.start) && !labels.containsKey(tcb.end) && !labels.containsKey(tcb.handler)) { Label s = new Label(); Label e = new Label(); Label h = new Label(); labels.put(tcb.start, s); labels.put(tcb.end, e); labels.put(tcb.handler, h); result.add(new TryCatchBlock(tcb.name, s, e, h, tcb.type, newIndex(mi, index++))); } else throw new RuntimeException("NYI"); // Need to add TableSwitch, LookupSwitch } else { result.add(i.copy(newIndex(mi, index++))); } } return result; }
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.SingleInsn.java
License:Open Source License
public boolean isAReturn() { if (opcode == Opcodes.ARETURN) return true; return false; }
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 a 2 s.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(); }
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) {// w w w.j a v a 2s .c om 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); }
From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java
License:Open Source License
private static void writeNullGetter(ClassWriter cw, String className, String methodName, String signature) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, signature, null, null); mv.visitCode();//from w w w . j a va 2 s. c om Label l0 = new Label(); mv.visitLabel(l0); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitInsn(Opcodes.ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", Naming.internalToDesc(className), null, l0, l1, 0); mv.visitLocalVariable("str", "Ljava/lang/String;", null, l0, l1, 1); // See comment above on ClassWriter.COMPUTE_FRAMES mv.visitMaxs(1, 2); mv.visitEnd(); }
From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java
License:Open Source License
private static void writeDumpMethod(ClassWriter cw, String className, EnvSymbolNames symbolNames) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "dump", "(Ljava/lang/Appendable;)Ljava/lang/Appendable;", null, new String[] { "java/io/IOException" }); mv.visitCode();// w w w .j a v a 2s . co m Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "within", Type.getType(HasAt.class).getDescriptor()); Label l1 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l1); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "within", Type.getType(HasAt.class).getDescriptor()); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(HasAt.class).getInternalName(), "at", "()Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn("\n"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); Label l4 = new Label(); mv.visitJumpInsn(Opcodes.GOTO, l4); mv.visitLabel(l1); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn("Not within anything.\n"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); mv.visitLabel(l4); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "verboseDump", "Z"); Label l5 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l5); int linebreaks = dumpFields(mv, className, EnvironmentClass.FVALUE, symbolNames, 0); dumpFields(mv, className, EnvironmentClass.FTYPE, symbolNames, linebreaks); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn("\n"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); mv.visitLabel(l5); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitInsn(Opcodes.ARETURN); Label l9 = new Label(); mv.visitLabel(l9); mv.visitLocalVariable("this", Naming.internalToDesc(className), null, l0, l9, 0); mv.visitLocalVariable("a", "Ljava/lang/Appendable;", null, l0, l9, 1); // See comment above on ClassWriter.COMPUTE_FRAMES mv.visitMaxs(2, 2); mv.visitEnd(); }
From source file:com.sun.fortress.compiler.nativeInterface.fortressConverter.java
License:Open Source License
private MethodVisitor generateNewBody(int access, String desc, String signature, String[] exceptions, String name, String newName) { Debug.debug(Debug.Type.COMPILER, 1, "generateNewBody: ", name, " with desc ", desc); SignatureParser sp = new SignatureParser(desc); List<String> desc_args = sp.getJVMArguments(); String desc_result = sp.getJVMResult(); List<String> fortress_args = new ArrayList<String>(); List<fortressConverter> convert_args = new ArrayList<fortressConverter>(); String fsig = "("; StringBuilder buf = new StringBuilder(); buf.append(fsig);//from ww w. j av a 2s . c o m for (String s : desc_args) { SignatureAndConverter s_a_c = toImplFFFF(s, name, false); buf.append(s_a_c.signature); fortress_args.add(s_a_c.signature); convert_args.add(s_a_c.converter); } fsig = buf.toString(); SignatureAndConverter s_a_c = toImplFFFF(desc_result, name, true); fsig = fsig + ")" + s_a_c.signature; fortressConverter convert_result = s_a_c.converter; // FORWARDING METHOD, only with type conversions on the way in/out! MethodVisitor mv = cv.visitMethod(access, name, fsig, signature, exceptions); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); int count = 0; for (String s : fortress_args) { fortressConverter converter = convert_args.get(count); mv.visitVarInsn(Opcodes.ALOAD, count++); converter.convertArg(mv, s); } Debug.debug(Debug.Type.COMPILER, 1, "className = ", inputClassName, " name = ", name, " access = ", access); mv.visitMethodInsn(Opcodes.INVOKESTATIC, inputClassName, name, sp.getSignature()); convert_result.convertResult(mv, s_a_c.signature); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); return mv; }
From source file:com.sun.fortress.compiler.OverloadSet.java
License:Open Source License
public void generateCall(MethodVisitor mv, int firstArgIndex, int one_if_method_closure) { if (!splitDone) { throw new CompilerError("Must split overload set before generating call(s)"); }// w w w. j a va2 s. c o m int l = specificDispatchOrder.length; TaggedFunctionName[] functionsToCall = new TaggedFunctionName[l]; for (int i = 0; i < l; i++) { functionsToCall[i] = getFunctionToCall(specificDispatchOrder[i]); } // create type structures for parameter types. TypeStructure[][] type_structures = new TypeStructure[l][]; MultiMap[] spmaps = new MultiMap[l]; TypeStructure[] return_type_structures = new TypeStructure[l]; for (int i = 0; i < l; i++) { TaggedFunctionName f = functionsToCall[i]; Functional eff = f.getF(); List<Param> parameters = f.getParameters(); MultiMap<String, TypeStructure> spmap = new MultiMap<String, TypeStructure>(); spmaps[i] = spmap; List<StaticParam> staticParams = staticParametersOf(f.getF()); Type rt = oa.getRangeType(eff); return_type_structures[i] = makeTypeStructure(rt, null, 1, 0, staticParams, eff); // skip parameters -- no 'this' for ordinary functions if (parameters.size() == 1 && oa.getDomainType(eff) instanceof TupleType) { TupleType tt = (TupleType) oa.getDomainType(eff); List<Type> tl = tt.getElements(); int storeAtIndex = tl.size(); // DRC back this out + firstArgIndex; // little dubious here, not sure we are getting the // right type structures for generic methods. what about 'self' TypeStructure[] f_type_structures = new TypeStructure[tl.size()]; type_structures[i] = f_type_structures; for (int j = 0; j < tl.size(); j++) { Type t = STypesUtil.insertStaticParams(tl.get(j), tt.getInfo().getStaticParams()); TypeStructure type_structure = makeTypeStructure(t, spmap, 1, storeAtIndex, staticParams, eff); f_type_structures[j] = type_structure; storeAtIndex = type_structure.successorIndex; } } else { int storeAtIndex = parameters.size(); // DRC back this out + firstArgIndex; TypeStructure[] f_type_structures = new TypeStructure[parameters.size()]; type_structures[i] = f_type_structures; for (int j = 0; j < parameters.size(); j++) { if (j != selfIndex()) { Type t = oa.getParamType(eff, j); TypeStructure type_structure = makeTypeStructure(t, spmap, 1, storeAtIndex, staticParams, eff); f_type_structures[j] = type_structure; storeAtIndex = type_structure.successorIndex; } } } } for (int i = 0; i < l; i++) { TaggedFunctionName f = functionsToCall[i]; TypeStructure[] f_type_structures = type_structures[i]; Label lookahead = null; boolean infer = false; List<StaticParam> staticParams = staticParametersOf(f.getF()); boolean last_case = i == l - 1; /* Trust the static checker; no need to verify * applicability of the last one. * Also, static parameters will be provided by static checker for the last one */ // Will need lookahead for the next one. lookahead = new Label(); // if this was a generic method that needs inference, we need to include the receiver argument // in the inference even if the firstArgIndex is 1 so that we can include it in inference // and dispatch //KBN-WIP is there a cleaner way to do this? int offset = (f_type_structures.length == specificDispatchOrder[i].getParameters().size()) ? firstArgIndex : 0; for (int j = 0; j < f_type_structures.length; j++) { if (j != selfIndex()) { //inference needed if the type structure contains generics TODO: do generics not appearing in the parameters make sense? probably not, but might need to deal with them. if (f_type_structures[j].containsTypeVariables) infer = true; } } if (infer || !last_case) for (int j = 0; j < f_type_structures.length; j++) { // Load actual parameter if (j != selfIndex()) { mv.visitVarInsn(Opcodes.ALOAD, j + offset); f_type_structures[j].emitInstanceOf(mv, lookahead, true); } } //Runtime inference for some cases if (infer) { @SuppressWarnings("unchecked") MultiMap<String, TypeStructure> staticTss = spmaps[i]; int localCount = f_type_structures[f_type_structures.length - 1].successorIndex; //counter for use storing stuff such as lower bounds //create type structures for lower bounds Map<StaticParam, TypeStructure> lowerBounds = new HashMap<StaticParam, TypeStructure>(); for (StaticParam sp : staticParams) lowerBounds.put(sp, makeParamTypeStructure(sp, localCount++, TypeStructure.COVARIANT)); //gather different types of bounds into Multimaps for use later MultiMap<StaticParam, StaticParam> relativeLowerBounds = new MultiMap<StaticParam, StaticParam>(); //form X :> Y MultiMap<StaticParam, Type> genericUpperBounds = new MultiMap<StaticParam, Type>(); //form X <: GenericStem[\ ... \] where Y appears in ... MultiMap<StaticParam, Type> concreteUpperBounds = new MultiMap<StaticParam, Type>(); //form X <: T where T contains no type variables for (int outer = 0; outer < staticParams.size(); outer++) { StaticParam outerSP = staticParams.get(outer); for (BaseType bt : outerSP.getExtendsClause()) { if (bt instanceof VarType) { // outerSP <: bt so outerSP will provide a lower bound on BT String varName = ((VarType) bt).getName().getText(); boolean found = false; for (int inner = 0; inner < outer && !found; inner++) { StaticParam innerSP = staticParams.get(inner); if (varName.equals(innerSP.getName().getText())) { relativeLowerBounds.putItem(innerSP, outerSP); // outerSP provides a lower bound on innerSP found = true; } } if (!found) throw new CompilerError( "Bad Scoping of static parameters found during runtime inference codegen:" + varName + " not declared before used in a bound"); } else if (bt instanceof AnyType) { //figure out if concrete or generic //do nothing - no need to add meaningless upper bound } else if (bt instanceof NamedType) { if (isGeneric(bt)) genericUpperBounds.putItem(outerSP, bt); else concreteUpperBounds.putItem(outerSP, bt); } } } //infer and load RTTIs for (int j = 0; j < staticParams.size(); j++) { StaticParam sp = staticParams.get(staticParams.size() - 1 - j); //reverse order due to left to right scoping Set<TypeStructure> instances = staticTss.get(sp.getName().getText()); //sort static parameters by their variance and put into //arrays using their local variable number List<Integer> invariantInstances = new ArrayList<Integer>(); List<Integer> covariantInstances = new ArrayList<Integer>(); List<Integer> contravariantInstances = new ArrayList<Integer>(); if (instances != null) for (TypeStructure ts : instances) { switch (ts.variance) { case TypeStructure.INVARIANT: invariantInstances.add(ts.localIndex); break; case TypeStructure.CONTRAVARIANT: contravariantInstances.add(ts.localIndex); break; case TypeStructure.COVARIANT: covariantInstances.add(ts.localIndex); break; default: throw new CompilerError("Unexpected Variance on TypeStructure during " + "generic instantiation analysis for overload dispatch"); } } // if any invariant instances, we must use that RTTI and check that //1) any other invariant instances are the same type (each subtypes the other) //2) any covariant instances are subtypes of the invariant instance //3) any contravariant instances are supertypes of the invariant instance if (invariantInstances.size() > 0) { //a valid instantiation must use the runtime type //of all invariant instances (which must all be the same) //thus, wlog, we can use the first invariant instance int RTTItoUse = invariantInstances.get(0); //1) for each other invariant instance, they must be the same //which we test by checking that each subtypes the other for (int k = 1; k < invariantInstances.size(); k++) { int RTTIcompare = invariantInstances.get(k); //RTTItoUse.runtimeSupertypeOf(RTTIcompare) mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail //RTTIcompare.runtimeSupertypeOf(RTTItoUse) mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare); mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail } //2) for each covariant instance, the runtime type (RTTIcompare) must be a // subtype of the instantiated type (RTTItoUse) for (int RTTIcompare : covariantInstances) { //RTTItoUse.runtimeSupertypeOf(RTTIcompare) mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail } //3) for each contravariant instance, the instantiated type (RTTItoUse) must be a // subtype of the runtime type (RTTIcompare) for (int RTTIcompare : contravariantInstances) { //RTTIcompare.runtimeSupertypeOf(RTTItoUse) mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare); mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail } //check lower bounds given by other variables Set<StaticParam> relativeLB = relativeLowerBounds.get(sp); if (relativeLB != null) for (StaticParam lb : relativeLB) { //RTTItoUse.runtimeSupertypeOf(otherLB) int otherOffset = lowerBounds.get(lb).localIndex; mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitVarInsn(Opcodes.ALOAD, otherOffset); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail } //verify meets upper bounds Set<Type> concreteUB = concreteUpperBounds.get(sp); if (concreteUB != null) for (Type cub : concreteUB) { //transform into RTTI generateRTTIfromStaticType(mv, cub); mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail } //generate more bounds for generic upper bounds Set<Type> genericUB = genericUpperBounds.get(sp); if (genericUB != null) for (Type gub : genericUB) { TypeStructure newTS = makeTypeStructure(gub, staticTss, TypeStructure.COVARIANT, localCount, staticParams, null); localCount = newTS.successorIndex; mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); newTS.emitInstanceOf(mv, lookahead, false); //fail if RTTItoUse doesn't have this structure } //checks out, so store the RTTI we will use into the lower bound for this parameter mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse); int index = lowerBounds.get(sp).localIndex; mv.visitVarInsn(Opcodes.ASTORE, index); } else if (contravariantInstances.size() == 0) { //we can do inference for covariant-only occurrences boolean started = false; if (covariantInstances.size() > 0) { started = true; mv.visitVarInsn(Opcodes.ALOAD, covariantInstances.get(0)); for (int k = 1; k < covariantInstances.size(); k++) { mv.visitVarInsn(Opcodes.ALOAD, covariantInstances.get(k)); //TODO: allow unions joinStackNoUnion(mv, lookahead); //fails if cannot join w/o union } } //incorporate lower bounds Set<StaticParam> relativeLB = relativeLowerBounds.get(sp); if (relativeLB != null) for (StaticParam lb : relativeLB) { mv.visitVarInsn(Opcodes.ALOAD, lowerBounds.get(lb).localIndex); if (started) { //join it in //TODO: allow unions joinStackNoUnion(mv, lookahead); } else { //start with this lower bound started = true; } } if (started) { //verify meets upper bounds Set<Type> concreteUB = concreteUpperBounds.get(sp); if (concreteUB != null) for (Type cub : concreteUB) { Label cleanup = new Label(); Label next = new Label(); mv.visitInsn(Opcodes.DUP); generateRTTIfromStaticType(mv, cub); //transform concrete bound into RTTI mv.visitInsn(Opcodes.SWAP); // LB <: CUB mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, cleanup); mv.visitJumpInsn(Opcodes.GOTO, next); mv.visitLabel(cleanup); mv.visitInsn(Opcodes.POP); mv.visitJumpInsn(Opcodes.GOTO, lookahead); mv.visitLabel(next); } //checks out, so store to lower bound of sp int index = lowerBounds.get(sp).localIndex; mv.visitVarInsn(Opcodes.ASTORE, index); //generate more bounds for generic upper bounds Set<Type> genericUB = genericUpperBounds.get(sp); if (genericUB != null) for (Type gub : genericUB) { TypeStructure newTS = makeTypeStructure(gub, staticTss, TypeStructure.COVARIANT, localCount, staticParams, null); localCount = newTS.successorIndex; mv.visitVarInsn(Opcodes.ALOAD, index); newTS.emitInstanceOf(mv, lookahead, false); //fail if candidate doesn't have this structure } } else { //Bottom is ok - no need to check upper bounds //or generate lower bounds mv.visitFieldInsn(Opcodes.GETSTATIC, Naming.RT_VALUES_PKG + "VoidRTTI", Naming.RTTI_SINGLETON, Naming.RTTI_CONTAINER_DESC); int index = lowerBounds.get(sp).localIndex; mv.visitVarInsn(Opcodes.ASTORE, index); } } else { //otherwise, we might need to do inference which is not implemented yet throw new CompilerError("non-invariant inference with contravariance not implemented"); } } //load instance cache table to avoid classloader when possible String tableName = this.generateClosureTableName(specificDispatchOrder[i]); //use original function for table name String tableOwner = this.generateClosureTableOwner(f); mv.visitFieldInsn(Opcodes.GETSTATIC, tableOwner, tableName, Naming.CACHE_TABLE_DESC); //load template class name String arrow = this.instanceArrowSchema(f); //NamingCzar.makeArrowDescriptor(f.getParameters(), f.getReturnType(),f.tagA); String functionName = this.functionName(f); String templateClass = Naming.genericFunctionPkgClass(Naming.dotToSep(f.tagA.getText()), functionName, Naming.LEFT_OXFORD + Naming.RIGHT_OXFORD, arrow); if (otherOverloadKeys.contains(templateClass)) { templateClass = Naming.genericFunctionPkgClass(Naming.dotToSep(f.tagA.getText()), NamingCzar.mangleAwayFromOverload(functionName), Naming.LEFT_OXFORD + Naming.RIGHT_OXFORD, arrow); //templateClass = NamingCzar.mangleAwayFromOverload(templateClass); } mv.visitLdcInsn(templateClass); String ic_sig; if (staticParams.size() > 6) { //use an array //load the function: RThelpers.loadClosureClass:(BAlongTree,String,RTTI[]) String paramList = Naming.CACHE_TABLE_DESC + NamingCzar.descString + Naming.RTTI_CONTAINER_ARRAY_DESC; ic_sig = Naming.makeMethodDesc(paramList, Naming.internalToDesc(NamingCzar.internalObject)); mv.visitLdcInsn(staticParams.size()); mv.visitTypeInsn(Opcodes.ANEWARRAY, Naming.RTTI_CONTAINER_TYPE); //dup array enough times to store RTTIs into it //know need at least 6 more mv.visitInsn(Opcodes.DUP); //first one to get arrays as top two elts on stack for (int numDups = staticParams.size() - 1; numDups > 0; numDups = numDups / 2) mv.visitInsn(Opcodes.DUP2); if (staticParams.size() % 2 == 0) mv.visitInsn(Opcodes.DUP); //if even, started halving with an odd number, so needs one last //store parameters into array for (int k = 0; k < staticParams.size(); k++) { int index = lowerBounds.get(staticParams.get(k)).localIndex; mv.visitLdcInsn(k); //index is the static param number mv.visitVarInsn(Opcodes.ALOAD, index); mv.visitInsn(Opcodes.AASTORE); } //array left on stack } else { //load the function: RTHelpers.loadClosureClass:(BAlongTree,(String,RTTI)^n)Object ic_sig = InstantiatingClassloader.jvmSignatureForOnePlusNTypes( Naming.CACHE_TABLE_TYPE + ";L" + NamingCzar.internalString, staticParams.size(), Naming.RTTI_CONTAINER_TYPE, Naming.internalToDesc(NamingCzar.internalObject)); //load parameter RTTIs for (int k = 0; k < staticParams.size(); k++) { int index = lowerBounds.get(staticParams.get(k)).localIndex; mv.visitVarInsn(Opcodes.ALOAD, index); } } mv.visitMethodInsn(Opcodes.INVOKESTATIC, Naming.RT_HELPERS, "loadClosureClass", ic_sig); //cast to object arrow int numParams = f.getParameters().size(); String objectAbstractArrow = NamingCzar.objectAbstractArrowTypeForNParams(numParams); InstantiatingClassloader.generalizedCastTo(mv, objectAbstractArrow); //if a method parameters converted //loadThisForMethods(mv); //load parameters for (int j = 0; j < f_type_structures.length; j++) { // Load actual parameter if (j != selfIndex()) { mv.visitVarInsn(Opcodes.ALOAD, j); // DRC back this out+ one_if_method_closure); // + firstArgIndex); KBN if a method, parameters already converted //no cast needed here - done by apply method } } //call apply method String objectArrow = NamingCzar.objectArrowTypeForNParams(numParams); String applySig = InstantiatingClassloader.jvmSignatureForNTypes(numParams, NamingCzar.internalObject, Naming.internalToDesc(NamingCzar.internalObject)); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, objectArrow, Naming.APPLY_METHOD, applySig); //cast to correct return type Type f_return = f.getReturnType(); if (f_return instanceof BottomType) { CodeGen.castToBottom(mv); } else { String returnType = NamingCzar.makeBoxedTypeName(f_return, f.tagA); InstantiatingClassloader.generalizedCastTo(mv, returnType); } } else { //no inferences needed loadThisForMethods(mv); for (int j = 0; j < f_type_structures.length; j++) { // Load actual parameter if (j != selfIndex()) { mv.visitVarInsn(Opcodes.ALOAD, j + firstArgIndex); InstantiatingClassloader.generalizedCastTo(mv, f_type_structures[j].fullname); } } String sig = jvmSignatureFor(f); invokeParticularMethod(mv, f, sig); Type f_return = f.getReturnType(); if (f_return instanceof BottomType) { CodeGen.castToBottom(mv); } } mv.visitInsn(Opcodes.ARETURN); if (lookahead != null) mv.visitLabel(lookahead); } }
From source file:com.sun.fortress.compiler.OverloadSet.java
License:Open Source License
/** * Invoke f (it's a forwarding call) with casts inserted as necessary. * /*w w w . j ava 2s .com*/ * @param mv * @param firstArgIndex * @param f */ private void generateLeafCall(MethodVisitor mv, int firstArgIndex, TaggedFunctionName f) { String sig = jvmSignatureFor(f); int i = firstArgIndex; List<Param> params = f.getParameters(); for (Param p : params) { mv.visitVarInsn(Opcodes.ALOAD, i); TypeOrPattern ty = p.getIdType().unwrap(); if (!(ty instanceof Type)) throw new CompilerError("Type is expected: " + ty); InstantiatingClassloader.generalizedCastTo(mv, NamingCzar.jvmBoxedTypeName((Type) ty, ifNone)); // mv.visitTypeInsn(Opcodes.CHECKCAST, NamingCzar.jvmBoxedTypeDesc((Type)ty, ifNone)); i++; } if (CodeGenerationPhase.debugOverloading >= 3) System.err.println("Emitting call " + f.tagF + sig); invokeParticularMethod(mv, f, sig); mv.visitInsn(Opcodes.ARETURN); }