List of usage examples for org.objectweb.asm Opcodes INVOKEVIRTUAL
int INVOKEVIRTUAL
To view the source code for org.objectweb.asm Opcodes INVOKEVIRTUAL.
Click Source Link
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)./*w w w . j a v a2s . 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. *//* w w w . java2s .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 ww.j ava2 s .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); }
From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java
License:Open Source License
/** * Implementing "static reflection" for the method putRaw so the * interpreter uses a switch instruction for ***PutRaw * based on the hash values of String names in this namespace. *///from www . j a va2s .c om private static void writeMethodPutRaw(ClassWriter cw, String className, String methodName, EnvironmentClass environmentClass, EnvSymbolNames symbolNames) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(" + STRING_DESCRIPTOR + environmentClass.descriptor() + ")V", null, null); mv.visitCode(); Label beginFunction = new Label(); mv.visitLabel(beginFunction); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STRING_INTERNALNAME, "hashCode", "()I"); mv.visitVarInsn(Opcodes.ISTORE, 3); 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 notFound = new Label(); putRawHelper(mv, className, environmentClass, hashCodeRelation, sortedCodes, notFound); mv.visitLabel(notFound); mv.visitInsn(Opcodes.RETURN); Label endFunction = new Label(); mv.visitLabel(endFunction); mv.visitLocalVariable("this", Naming.internalToDesc(className), null, beginFunction, endFunction, 0); mv.visitLocalVariable("queryString", STRING_DESCRIPTOR, null, beginFunction, endFunction, 1); mv.visitLocalVariable("value", environmentClass.descriptor(), null, beginFunction, endFunction, 2); mv.visitLocalVariable("queryHashCode", "I", null, beginLoop, endFunction, 3); // See comment above on ClassWriter.COMPUTE_FRAMES mv.visitMaxs(2, 4); mv.visitEnd(); }
From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java
License:Open Source License
private static void putRawBaseCase(MethodVisitor mv, String className, Relation<String, Integer> hashCodeRelation, EnvironmentClass environmentClass, int code, Label notFound) {/*from w w w . j ava2s. co 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 afterSetValue = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, afterSetValue); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 2); String idString = testString + environmentClass.namespace(); mv.visitFieldInsn(Opcodes.PUTFIELD, className, Naming.mangleIdentifier(idString), environmentClass.descriptor()); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(afterSetValue); } mv.visitJumpInsn(Opcodes.GOTO, notFound); }
From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java
License:Open Source License
private static void writeRemoveMethod(ClassWriter cw, String className, String methodName, String invokeMethod, EnvironmentClass environmentClass) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(Ljava/lang/String;)V", null, null); mv.visitCode();/*from w w w. ja va 2 s . co m*/ Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, invokeMethod, "(Ljava/lang/String;" + environmentClass.descriptor() + ")V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(Opcodes.RETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitLocalVariable("this", Naming.internalToDesc(className), null, l0, l2, 0); mv.visitLocalVariable("name", "Ljava/lang/String;", null, l0, l2, 1); // See comment above on ClassWriter.COMPUTE_FRAMES mv.visitMaxs(3, 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 w w w.ja va 2 s . c om 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.nativeInterface.fortressConverter.java
License:Open Source License
int opcode() { return Opcodes.INVOKEVIRTUAL; }
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)"); }//from w w w. j a v a 2s .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
private void joinStackNoUnion(MethodVisitor mv, Label lookahead) { Label try2 = new Label(); Label next = new Label(); Label cleanup = new Label(); mv.visitInsn(Opcodes.DUP2); //#2 <: #1 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, try2); //if no, try opposite mv.visitInsn(Opcodes.POP); // want #1 (lower on the stack) mv.visitJumpInsn(Opcodes.GOTO, next); //done mv.visitLabel(try2); mv.visitInsn(Opcodes.SWAP);/* www.j a v a2s .com*/ mv.visitInsn(Opcodes.DUP2); // #1 <: #2 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); mv.visitJumpInsn(Opcodes.IFEQ, cleanup); //if no, fail dispatch mv.visitInsn(Opcodes.POP); // want #2 (now lower on the stack) mv.visitJumpInsn(Opcodes.GOTO, next); //done mv.visitLabel(cleanup); mv.visitInsn(Opcodes.POP2); mv.visitJumpInsn(Opcodes.GOTO, lookahead); mv.visitLabel(next); }