List of usage examples for org.objectweb.asm Opcodes INVOKEINTERFACE
int INVOKEINTERFACE
To view the source code for org.objectweb.asm Opcodes INVOKEINTERFACE.
Click Source Link
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.MethodInsn.java
License:Open Source License
public boolean isInterfaceMethod() { return this.opcode == Opcodes.INVOKEINTERFACE; }
From source file:com.sun.fortress.compiler.codegen.CodeGen.java
License:Open Source License
public void forTraitDecl(TraitDecl x) { debug("forTraitDecl", x); TraitTypeHeader header = x.getHeader(); Id traitname = (Id) header.getName(); String traitname_string = traitname.getText(); if (traitname_string.equals("Any") && traitname.getApiName().isNone()) { String api_stringname = thisApi().getText(); if (api_stringname.equals("AnyType")) return; }/*from w w w .ja v a2s . c om*/ TraitTypeHeader original_header = x.getHeader(); List<TraitTypeWhere> extendsC = header.getExtendsClause(); boolean canCompile = // NOTE: Presence of excludes or comprises clauses should not // affect code generation once type checking is complete. header.getWhereClause().isNone() && // no where clause header.getThrowsClause().isNone() && // no throws clause header.getContract().isNone() && // no contract Modifiers.TraitMod.containsAll(header.getMods()); debug("forTraitDecl", x, " decls = ", header.getDecls(), " extends = ", extendsC); if (!canCompile) throw sayWhat(x); // Map<String, String> xlation = new HashMap<String, String>(); List<String> splist = new ArrayList<String>(); List<StaticParam> original_static_params = header.getStaticParams(); Naming.XlationData xldata = xlationData(Naming.TRAIT_GENERIC_TAG); // First let's do the interface class // String classFile = NamingCzar.makeInnerClassName(packageAndClassName, // NodeUtil.getName(x).getText()); /* * This will want refactoring into NamingCzar sooner or later. * I decided that the least-confusion convention for implementing * classes for generic traits was to use the Generic[\parameters\]$whatever * convention. This may require enhancements to the mangling code, but * once that is done it will cause least-confusion for everyone else * later. */ Id classId = NodeUtil.getName(x); ClassNameBundle cnb = new_ClassNameBundle(classId, original_static_params, xldata); String erasedSuperI = EMIT_ERASED_GENERICS && cnb.isGeneric ? cnb.stemClassName : ""; if (EMIT_ERASED_GENERICS && cnb.isGeneric) { emitErasedClassFor(cnb, (TraitObjectDecl) x); } inATrait = true; currentTraitObjectDecl = x; springBoardClass = cnb.className + NamingCzar.springBoard; String springBoardClassOuter = cnb.fileName + NamingCzar.springBoard; String abstractSuperclass; traitOrObjectName = cnb.className; String[] superInterfaces = NamingCzar.extendsClauseToInterfaces(extendsC, component.getName(), erasedSuperI); if (cnb.className.equals("fortress/AnyType$Any")) { superInterfaces = new String[0]; abstractSuperclass = NamingCzar.FValueType; } else { abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; } CodeGenClassWriter prev = cw; cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, prev); cw.visitSource(NodeUtil.getSpan(x).begin.getFileName(), null); cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, cnb.className, null, NamingCzar.internalObject, superInterfaces); dumpTraitMethodSigs(header.getDecls()); initializedStaticFields_TO = new ArrayList<InitializedStaticField>(); //no instance fields for traits emitRttiField(cnb); optionalStaticsAndClassInitForTO(classId, cnb, false); if (cnb.isGeneric) { cw.dumpClass(cnb.fileName, xldata); } else { cw.dumpClass(cnb.fileName); } // Doing this to get an extended type analyzer for overloaded method chaining. CodeGen newcg = new CodeGen(this, typeAnalyzer.extendJ(header.getStaticParams(), header.getWhereClause())); // Now let's do the springboard inner class that implements this interface. newcg.cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, prev); newcg.cw.visitSource(NodeUtil.getSpan(x).begin.getFileName(), null); // Springboard *must* be abstract if any methods / fields are abstract! // In general Springboard must not be directly instantiable. newcg.cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC | ACC_ABSTRACT, springBoardClass, null, abstractSuperclass, new String[] { cnb.className }); debug("Start writing springboard class ", springBoardClass); // simple init method newcg.basicInitMethod(abstractSuperclass); debug("Finished init method ", springBoardClass); newcg.initializedStaticFields_TO = new ArrayList<InitializedStaticField>(); // Overloads will tell us which methods need forwarding, // but they don't yet. Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> overloads = newcg .dumpOverloadedMethodChaining(superInterfaces, true); if (OVERLOADED_METHODS) newcg.typeLevelOverloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), overloads, newcg.typeAnalyzer, newcg.cw, newcg, new OverloadSet.TraitOrObjectFactory(Opcodes.INVOKEINTERFACE, cnb, newcg)); newcg.dumpTraitDecls(header.getDecls()); newcg.dumpMethodChaining(superInterfaces, true); // dumpErasedMethodChaining(superInterfaces, true); newcg.optionalStaticsAndClassInitForTO(classId, cnb, false); debug("Finished dumpDecls ", springBoardClass); if (cnb.isGeneric) { /* Not dead sure this is right * Reasoning is that if the springboard IS ever referenced in a * generic context (how????) it is in fact a class, so it needs * INVOKEVIRTUAL. */ newcg.cw.dumpClass(springBoardClassOuter, xldata.setTraitObjectTag(Naming.OBJECT_GENERIC_TAG)); } else { newcg.cw.dumpClass(springBoardClassOuter); } // Now lets dump out the functional methods at top level. cw = prev; emittingFunctionalMethodWrappers = true; // Have to use the origial header to get the signatures right. dumpTraitDecls(original_header.getDecls()); emitOrphanedFunctionalMethods(traitname); emittingFunctionalMethodWrappers = false; debug("Finished dumpDecls for parent"); inATrait = false; currentTraitObjectDecl = null; traitOrObjectName = null; springBoardClass = null; initializedStaticFields_TO = null; RttiClassAndInterface(x, cnb, xldata); }
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();/*from w w w . j a v a 2 s .c o 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.environments.TopLevelEnvGen.java
License:Open Source License
private static int dumpFields(MethodVisitor mv, String className, EnvironmentClass eClass, EnvSymbolNames symbolNames, int linebreaks) { for (String fieldName : symbolNames.getSymbolNames(eClass)) { Label l6 = new Label(); mv.visitLabel(l6);//from ww w. j a v a 2 s . c o m mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn("(" + fieldName + " = "); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); Label l7 = new Label(); mv.visitLabel(l7); mv.visitVarInsn(Opcodes.ALOAD, 0); String idString = fieldName + eClass.namespace(); mv.visitFieldInsn(Opcodes.GETFIELD, className, Naming.mangleIdentifier(idString), eClass.descriptor()); Label l8 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l8); Label l9 = new Label(); mv.visitLabel(l9); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, Naming.mangleIdentifier(idString), eClass.descriptor()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, eClass.internalName(), "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); Label afterNull = new Label(); mv.visitJumpInsn(Opcodes.GOTO, afterNull); mv.visitLabel(l8); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn("null"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); mv.visitLabel(afterNull); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitLdcInsn(") "); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;"); mv.visitInsn(Opcodes.POP); linebreaks = (linebreaks + 1) % 5; if (linebreaks == 0) { 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); } } return linebreaks; }
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.ja v a2 s.co 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.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
private static byte[] instantiateWrappedArrow(String name, List<String> parameters) { ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); /*// ww w .ja v a2 s .c om * extends AbstractArrow[\parameters\] * * private final Arrow[\Object...Object\] wrappee * * Arrow[\Object...Object\] getWrappee() * * WrappedArrow[\parameters\](Arrow[\Object...Object\] _wrappee) * * public range_parameter apply( domain_parameters ) = * (range_parameter) wrappee.apply( domain_parameters ) */ Triple<List<String>, List<String>, String> stuff = normalizeArrowParameters(parameters); List<String> flat_params_and_ret = stuff.getA(); List<String> tupled_params_and_ret = stuff.getB(); String tupleType = stuff.getC(); List<String> flat_obj_params_and_ret = Useful.applyToAll(flat_params_and_ret, toJLO); List<String> norm_obj_params_and_ret = normalizeArrowParametersAndReturn(flat_obj_params_and_ret); List<String> norm_params_and_ret = normalizeArrowParametersAndReturn(flat_params_and_ret); String extendsClass = stringListToGeneric(ABSTRACT_ARROW, norm_params_and_ret); // List<String> objectified_parameters = Useful.applyToAll(flat_params_and_ret, toJLO); //String obj_sig = stringListToGeneric("AbstractArrow", objectified_parameters); String obj_intf_sig = stringListToGeneric(Naming.ARROW_TAG, norm_obj_params_and_ret); String wrappee_name = "wrappee"; //extends AbstractArrow[\parameters\] cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER, name, null, extendsClass, null); // private final Arrow[\Object...Object\] wrappee cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, wrappee_name, Naming.internalToDesc(obj_intf_sig), null /* for non-generic */, null /* instance has no value */); // WrappedArrow[\parameters\](Arrow[\Object...Object\] _wrappee) MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(" + Naming.internalToDesc(obj_intf_sig) + ")V", null, null); mv.visitCode(); // super() mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, extendsClass, "<init>", "()V"); // this.wrappee = wrappee mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, name, wrappee_name, Naming.internalToDesc(obj_intf_sig)); // done mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // getWrappee mv = cw.visitMethod(ACC_PUBLIC, getWrappee, "()" + Naming.internalToDesc(obj_intf_sig), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, name, wrappee_name, Naming.internalToDesc(obj_intf_sig)); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // public range_parameter apply( domain_parameters ) = // (range_parameter) wrappee.apply( domain_parameters ) String flattened_apply_sig; if (parameters.size() == 2 && parameters.get(0).equals(Naming.INTERNAL_SNOWMAN)) flattened_apply_sig = arrowParamsToJVMsig(parameters.subList(1, 2)); else flattened_apply_sig = arrowParamsToJVMsig(flat_params_and_ret); String obj_apply_sig = arrowParamsToJVMsig(flat_obj_params_and_ret); mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, flattened_apply_sig, null, null); mv.visitCode(); // load wrappee for delegation mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, name, wrappee_name, Naming.internalToDesc(obj_intf_sig)); // Push parameters. // i is indexed so that it corresponds to parameters pushed, even though // the types are ignored here (for now). for (int i = 0; i < flat_params_and_ret.size() - 1; i++) { String t = flat_params_and_ret.get(i); if (!t.equals(Naming.INTERNAL_SNOWMAN)) { mv.visitVarInsn(ALOAD, i + 1); } else { /* we are calling the object-interface version of this, * we need something on the stack, or else it will fail. * * This is also a naming/refactoring FAIL; this information * needs to come from somewhere else. */ mv.visitInsn(Opcodes.ACONST_NULL); // mv.visitMethodInsn(Opcodes.INVOKESTATIC, // Naming.runtimeValues + "FVoid", "make", // "()" + Naming.internalToDesc(Naming.runtimeValues + "FVoid")); } } mv.visitMethodInsn(INVOKEINTERFACE, obj_intf_sig, Naming.APPLY_METHOD, obj_apply_sig); // mv.visitTypeInsn(Opcodes.CHECKCAST, parameters.get(parameters.size()-1)); generalizedCastTo(mv, flat_params_and_ret.get(flat_params_and_ret.size() - 1)); // done mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); //getRTTI - forwards to wrapped arrow { mv = cw.visitMethod(ACC_PUBLIC, Naming.RTTI_GETTER, "()" + Naming.RTTI_CONTAINER_DESC, null, null); mv.visitCode(); // load wrappee for delegation mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, name, wrappee_name, Naming.internalToDesc(obj_intf_sig)); //invoke interface getRTTI method mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Naming.ANY_TYPE_CLASS, Naming.RTTI_GETTER, Naming.STATIC_PARAMETER_GETTER_SIG); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
/** * A union type. Iterate over the members of the union * /*from w w w . j av a 2s . co m*/ * @param dename * @param parameters * @return */ private static byte[] instantiateUnion(String dename, List<String> parameters) { /* */ ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); final int n = parameters.size(); String[] superInterfaces = {}; cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC, dename, null, "java/lang/Object", superInterfaces); // Intersect all the interfaces to find those common to all members // of the union. HashSet<Class> intersected_tc_ifs = null; for (String member : parameters) { String for_loading = Naming.sepToDot(Naming.mangleFortressIdentifier(member)); Class cl = null; try { ClassLoader icl = MainWrapper.icl; cl = icl.loadClass(for_loading); // cl = Class.forName(for_loading); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } HashSet<Class> tc_ifs = new HashSet<Class>(); addTransitiveImplements(cl, tc_ifs); if (intersected_tc_ifs == null) intersected_tc_ifs = tc_ifs; else intersected_tc_ifs.retainAll(tc_ifs); } // For each distinct method of the interfaces in the intersection, // ignoring self type, emit a static forwarding method, where // the first parameter is cast to an interface type (one that // has that method) and then it is invoke-interfaced. BATree<String, Method> forwarded = new BATree<String, Method>(DefaultComparator.V); for (Class an_if : intersected_tc_ifs) { // emit a forwarding method for each method in an_if if (an_if.isInterface()) { Method[] methods = an_if.getDeclaredMethods(); for (Method m : methods) { String nm = m.getName(); Class[] pts = m.getParameterTypes(); Class rt = m.getReturnType(); StringBuffer key = new StringBuffer(); key.append(nm); key.append("("); for (Class pt : pts) { String s = pt.getName(); if (pt.isPrimitive()) { key.append(s); } else { key.append("L"); key.append(Naming.dotToSep(s)); key.append(";"); } } key.append(")"); String s = Naming.dotToSep(rt.getName()); key.append("L" + s + ";"); forwarded.put(key.toString(), m); } } } // For each interface-qualified method defined in the intersection // of interfaces, emit a forwarding method. for (String key : forwarded.keySet()) { Method m = forwarded.get(key); int ploc = key.indexOf('('); String nm = Naming.demangleFortressIdentifier(key.substring(0, ploc)); String callee_sig = Naming.demangleFortressDescriptor(key.substring(ploc)); String sig = "(" + Naming.ERASED_UNION_DESC + callee_sig.substring(1); // Static, forwarding method MethodVisitor mv = cw.visitCGMethod(ACC_PUBLIC + ACC_STATIC, nm, sig, null, null); String an_interface = Naming.dotToSep(m.getDeclaringClass().getName()); String the_interface = Naming.demangleFortressIdentifier(an_interface); int stack_index = 0; mv.visitVarInsn(ALOAD, stack_index++); // 'this' mv.visitTypeInsn(CHECKCAST, the_interface); Class[] pts = m.getParameterTypes(); for (Class pt : pts) { String s = pt.getName(); if (pt.isPrimitive()) { switch (s.charAt(0)) { case 'D': mv.visitVarInsn(DLOAD, stack_index++); // param stack_index++; break; case 'F': mv.visitVarInsn(FLOAD, stack_index++); // param break; case 'I': case 'S': case 'C': case 'B': case 'Z': mv.visitVarInsn(ILOAD, stack_index++); // param break; case 'J': mv.visitVarInsn(LLOAD, stack_index++); // param stack_index++; break; } } else { mv.visitVarInsn(ALOAD, stack_index++); // param } } mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, the_interface, nm, callee_sig); char last = sig.charAt(sig.length() - 1); if (last == 'V') voidEpilogue(mv); else areturnEpilogue(mv); } cw.visitEnd(); return cw.toByteArray(); }
From source file:com.sun.fortress.runtimeSystem.MethodInstantiater.java
License:Open Source License
public void visitMethodInsn(int opcode, String owner, String name, String desc) { String oname = name;//from w w w . j a va 2 s. co m String descSplice = ""; // used to transform calls to union/intersection if (owner.equals(Naming.magicInterpClass)) { name = xlation.getTypeName(name); String op = Naming.encodedOp(name); String s = Naming.encodedConst(name); if (op.equals(Naming.hashMethod)) { long hash_sargs = MagicNumbers.hashStringLong(s); mv.visitLdcInsn(Long.valueOf(hash_sargs)); } else if (op.equals(Naming.stringMethod)) { mv.visitLdcInsn(s); } else { throw new Error("Invocation of magic class Method '" + oname + "' ('" + name + "') seen, but op is not recognized."); } } else { String new_owner = xlation.getTypeName(owner); // demangled. if (opcode == Opcodes.INVOKEINTERFACE && !new_owner.equals(owner)) { if (new_owner.contains(Naming.LEFT_OXFORD)) { if (new_owner.startsWith(Naming.UNION_OX)) { // replace invokeinterface with invokestatic, modify desc opcode = Opcodes.INVOKESTATIC; descSplice = Naming.ERASED_UNION_DESC; } else if (!new_owner.startsWith(Naming.ARROW_OX) && !new_owner.startsWith(Naming.TUPLE_OX)) { Naming.XlationData xldata = icl.xlationForGeneric(new_owner); String stem_sort = xldata.first(); if (stem_sort.equals(Naming.OBJECT_GENERIC_TAG) // || stem_sort.equals(Naming.FUNCTION_GENERIC_TAG) ) opcode = Opcodes.INVOKEVIRTUAL; else { // do nothing } } else { // do nothing } } else { String new_owner_class_name = Naming.mangleFortressIdentifier(new_owner); new_owner_class_name = new_owner_class_name.replaceAll("[/]", "."); try { Class cl = Class.forName(new_owner_class_name, true, icl); if (cl.isInterface()) { // Do nothing } else { opcode = Opcodes.INVOKEVIRTUAL; } } catch (ClassNotFoundException e) { // Do nothing, not our problem } } } name = xlation.getMethodName(name); desc = xlation.getMethodDesc(desc); if (descSplice != null) desc = "(" + descSplice + desc.substring(1); mv.visitMethodInsn(opcode, new_owner, name, desc); } }
From source file:com.trigersoft.jaque.expression.ExpressionMethodVisitor.java
License:Apache License
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { Type[] argsTypes = Type.getArgumentTypes(desc); Class<?>[] parameterTypes = new Class<?>[argsTypes.length]; for (int i = 0; i < argsTypes.length; i++) parameterTypes[i] = _classVisitor.getClass(argsTypes[i]); Expression[] arguments = new Expression[argsTypes.length]; for (int i = argsTypes.length; i > 0;) { i--;// w w w. j av a 2 s.co m arguments[i] = TypeConverter.convert(_exprStack.pop(), parameterTypes[i]); } Expression e; switch (opcode) { case Opcodes.INVOKESPECIAL: if (name.equals("<init>")) { try { e = Expression.newInstance(_exprStack.pop().getResultType(), parameterTypes, arguments); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } _exprStack.pop(); // going to re-add it, which is not the JVM // semantics break; } case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKEINTERFACE: try { e = Expression.invoke( TypeConverter.convert(_exprStack.pop(), _classVisitor.getClass(Type.getObjectType(owner))), name, parameterTypes, arguments); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } break; case Opcodes.INVOKESTATIC: case Opcodes.INVOKEDYNAMIC: try { e = Expression.invoke(_classVisitor.getClass(Type.getObjectType(owner)), name, parameterTypes, arguments); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } break; default: throw new IllegalArgumentException("opcode: " + opcode); } _exprStack.push(e); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.RecordMapPropertyAdapter.java
@Override public AssignableValue index(final BytecodeExpression target, final BytecodeExpression propertyName) { return new AssignableValue() { @Override/* ww w . ja v a 2 s . c om*/ public TypeWidget getType() { return AnyTypeWidget.getInstance(); } @Override public BytecodeSequence write(BytecodeExpression value) { return new PopExpression(new InvokeExpression(Map.class, Opcodes.INVOKEINTERFACE, "put", Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(Object.class), Type.getType(Object.class)), AnyTypeWidget.getInstance(), target, ImmutableList.of(propertyName, value))); } @Override public BytecodeSequence write(final TypeWidget top) { return new BytecodeSequence() { @Override public void generate(CodeEmitter code) { AssignableValue out = code.allocate(top); out.write(top); write(out); } }; } @Override public void generate(CodeEmitter code) { read().generate(code); } @Override public BytecodeExpression read() { return new InvokeExpression(RecordPropertyAdapter.class, Opcodes.INVOKESTATIC, "get", Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(Record.class), Type.getType(Object.class)), AnyTypeWidget.getInstance(), null, ImmutableList.of(target, propertyName)); } }; }