List of usage examples for org.objectweb.asm MethodVisitor visitVarInsn
public void visitVarInsn(final int opcode, final int var)
From source file:com.sun.fortress.runtimeSystem.Instantiater.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // necessary? name = oprs.getMethodName(name);//w ww . java 2s .com //System.out.println("old desc=" + desc); //desc = types.getMethodDesc(desc); //System.out.println("new desc=" + desc); String newDesc = types.getMethodDesc(desc); MethodVisitor mv = cv.visitMethod(access, name, newDesc, signature, exceptions); if (!desc.equals(newDesc)) { // catch flattened tuples String params = desc.substring(desc.indexOf("(") + 1, //TODO: wrong if nested parens desc.indexOf(")")); String newParams = newDesc.substring(newDesc.indexOf("(") + 1, newDesc.indexOf(")")); if (params.split(";").length == 1 && //single generic parameter newParams.startsWith("LTuple")) { //tuple substituted in //System.out.println(access + " " + name + " " + signature + " " +this.instanceName); if ((this.access_flags & Opcodes.ACC_INTERFACE) == 0 && //not in an interface (access & Opcodes.ACC_STATIC) == 0) { //and not a static method, so generate a body //extract the parameters and create strings for the types List<String> paramList = InstantiationMap.extractStringParameters(newParams, newParams.indexOf(Naming.LEFT_OXFORD), InstantiationMap.templateClosingRightOxford(newParams), new ArrayList<String>()); String rawParams = ""; for (String p : paramList) rawParams = rawParams + Naming.internalToDesc(p); final String altDesc = newDesc.substring(0, newDesc.indexOf("(") + 1) + rawParams + newDesc.substring(newDesc.indexOf(")"), newDesc.length()); String tuple_params = InstantiatingClassloader.stringListToTuple(paramList); String make_sig = InstantiatingClassloader.toJvmSig(paramList, Naming.javaDescForTaggedFortressType(tuple_params)); MethodVisitor altMv = cv.visitMethod(access, name, altDesc, signature, exceptions); altMv.visitVarInsn(Opcodes.ALOAD, 0); //load this final int n = paramList.size(); //load the parameters for (int i = 1; i <= n; i++) { altMv.visitVarInsn(Opcodes.ALOAD, i); } altMv.visitMethodInsn(Opcodes.INVOKESTATIC, InstantiatingClassloader.CONCRETE_ + tuple_params, "make", make_sig); //create a tuple from the parameters if (name.equals("<init>")) { altMv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instanceName, name, newDesc); //call original method altMv.visitInsn(Opcodes.RETURN); //return } else { altMv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.instanceName, name, newDesc); //call original method altMv.visitInsn(Opcodes.ARETURN); //return } altMv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); altMv.visitEnd(); } } } return new MethodInstantiater(mv, types, icl); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
public static String closureClassPrefix(String name, ManglingClassWriter cw, String staticClass, String sig, boolean is_forwarding_closure, String forceCastParam0, List<InitializedStaticField> statics) { int env_loc = name.indexOf(Naming.ENVELOPE); int last_dot = name.substring(0, env_loc).lastIndexOf('$'); String api = name.substring(0, last_dot); String suffix = name.substring(last_dot + 1); env_loc = suffix.indexOf(Naming.ENVELOPE); // followed by $ String fn = is_forwarding_closure ? suffix.substring(0, env_loc) : Naming.APPLIED_METHOD; String ft = suffix.substring(env_loc + 2); // skip $ following ENVELOPE // Normalize out leading HEAVY_CROSS, if there is one. {//from w w w . j a v a 2 s .c o m if (ft.charAt(0) == Naming.HEAVY_CROSS_CHAR) ft = ft.substring(1); // Allow bound-specific disambiguation in a suffix int hvy_x = ft.indexOf(Naming.HEAVY_X_CHAR); if (hvy_x != -1) ft = ft.substring(0, hvy_x); int left = ft.indexOf(Naming.LEFT_OXFORD); int right = ft.lastIndexOf(Naming.RIGHT_OXFORD); List<String> parameters = RTHelpers.extractStringParameters(ft, left, right); Triple<List<String>, List<String>, String> stuff = normalizeArrowParameters(parameters); List<String> flat_params_and_ret = stuff.getA(); if (flat_params_and_ret.size() == 2 && flat_params_and_ret.get(0).equals(Naming.INTERNAL_SNOWMAN)) flat_params_and_ret = flat_params_and_ret.subList(1, 2); if (sig == null) sig = arrowParamsToJVMsig(flat_params_and_ret); } SignatureParser sp = new SignatureParser(sig); /* * Recipe: * need to emit class "name". * It needs to extend AbstractArrow[\parameters\] * It needs to contain * RT apply (params_except_last) { * return api.fn(params_except_last); * } */ FieldVisitor fv; MethodVisitor mv; String superClass = ABSTRACT_ + ft; // ft is assumed to begin with "Arrow" name = api.replace(".", "/") + '$' + suffix; final String final_name = name; //String desc = Naming.internalToDesc(name); final String field_desc = Naming.internalToDesc(ft); // Begin with a class cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER, name, null, superClass, null); statics.add(new InitializedStaticField.StaticForClosureField(field_desc, final_name)); //RTTI field // statics.add(new InitializedStaticField() { // // @Override // public void forClinit(MethodVisitor init_mv) { // MethodInstantiater mi = new MethodInstantiater(init_mv, null, null); // mi.rttiReference(final_name + Naming.RTTI_CLASS_SUFFIX); // init_mv.visitFieldInsn(PUTSTATIC, final_name, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC); // } // // @Override // public String asmName() { // return Naming.RTTI_FIELD; // } // // @Override // public String asmSignature() { // return Naming.RTTI_CONTAINER_DESC; // }}); // Instance init does nothing special mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // Supertype is mangle("Abstract"+ft) mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // What if staticClass is compiler builtin? How do we know? if (staticClass == null) staticClass = api; staticClass = staticClass.replace(".", "/"); if (LOG_LOADS) System.err.println(name + ".apply" + sig + " concrete\nparams = " + sp); // KBN 06/2011 handled above now // Monkey business to deal with case of "void" args. //int sz = parameters.size(); // Last parameter is actually result type! // But we need to include an extra arg in sz to represent the closure itself (this). // if (sz==2 && Naming.INTERNAL_SNOWMAN.equals(parameters.get(0))) { // Arity 1 (sz 2) with void parameter should actually be arity 0 (sz 1). // sz = 1; //} // Emit a method with well-known name ("apply", most likely) // to forward calls from the instance to the static, which our // caller will supply. Note that the static class can be a // different class. forwardingMethod(cw, Naming.APPLY_METHOD, ACC_PUBLIC, 0, staticClass, fn, INVOKESTATIC, sig, sig, sp.paramCount() + 1, false, forceCastParam0); return fn; }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
/** * Emits a forwarding method./*from ww w. j a va 2 s . co m*/ * * Cases: * apply static, target static * apply instance, target static * apply instance, target instance * * @param cw Classwriter that will write the forwarding method * @param thisName name of the generated (forwarding) method * @param thisModifiers modifiers for the generated (forwarding) method * @param selfIndex index of the self parameter, if any * @param fwdClass class for the target method * @param fwdName name of the target method * @param fwdOp the appropriate INVOKE opcode for the forward * @param thisSig the signature of the generated (forwarding) method * @param fwdSig the signature of the target (called) method * @param selfCastSig a full signature containing self at selfIndex * @param nparamsIncludingSelf number of parameters, including self (if any) * @param pushSelf if true, push self first, using selfIndex to find it * @param forceCastParam0 cast param 0, even if it is not self. This is for * implementation of generic methods. It may need * to be generalized to all params, not entirely sure. * @param castReturn cast the return type to what it "ought" to be. * deals with BottomType case. Makes verifier happy. */ public static void forwardingMethod(ClassWriter cw, String thisName, int thisModifiers, int selfIndex, String fwdClass, String fwdName, int fwdOp, String thisSig, String fwdSig, String selfCastSig, int nparamsIncludingSelf, boolean pushSelf, String forceCastParam0, boolean castReturn) { String selfSig = null; if (pushSelf) { if (selfCastSig != null) { selfSig = Naming.nthSigParameter(selfCastSig, selfIndex); selfSig = selfSig.substring(1, selfSig.length() - 1); } if ((thisModifiers & ACC_STATIC) != 0) { if (fwdOp != INVOKESTATIC) { // receiver has explicit self, fwd is dotted. fwdSig = Naming.removeNthSigParameter(fwdSig, selfIndex); } } else if (fwdOp == INVOKESTATIC) { thisSig = Naming.removeNthSigParameter(thisSig, selfIndex); } } else if (selfIndex >= 0 && (thisModifiers & ACC_STATIC) != 0) { // Dropping explicit self parameter, so remove from signature. fwdSig = Naming.removeNthSigParameter(fwdSig, selfIndex); } if (forceCastParam0 != null) { fwdSig = Naming.replaceNthSigParameter(fwdSig, 0, Naming.internalToDesc(forceCastParam0)); } // System.err.println("Forwarding "+thisName+":"+thisSig+ // " arity "+nparamsIncludingSelf+"\n"+ // " to "+fwdClass+"."+fwdName+":"+fwdSig); MethodVisitor mv = cw.visitMethod(thisModifiers, thisName, thisSig, null, null); mv.visitCode(); SignatureParser sp = new SignatureParser(fwdSig); int parsed_arg_cursor = 0; if (pushSelf) { mv.visitVarInsn(ALOAD, selfIndex); if (selfSig != null) mv.visitTypeInsn(CHECKCAST, selfSig); if (fwdOp == INVOKESTATIC) parsed_arg_cursor++; } pushParamsNotSelf(selfIndex, nparamsIncludingSelf, forceCastParam0, mv, sp, parsed_arg_cursor); mv.visitMethodInsn(fwdOp, fwdClass, fwdName, fwdSig); // optional CAST here for tuple and arrow String tyName = Naming.sigRet(thisSig); if (tyName.startsWith(Naming.TUPLE_OX) || tyName.startsWith(Naming.ARROW_OX) || castReturn) { String tyNameFrom = Naming.sigRet(fwdSig); InstantiatingClassloader.generalizedCastTo(mv, tyName); } mv.visitInsn(ARETURN); mv.visitMaxs(2, 3); mv.visitEnd(); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
/** * @param selfIndex/*w w w . j a va 2 s. com*/ * @param nparamsIncludingSelf * @param forceCastParam0 * @param mv * @param sp * @param parsed_arg_cursor */ public static void pushParamsNotSelf(int selfIndex, int nparamsIncludingSelf, String forceCastParam0, MethodVisitor mv, SignatureParser sp, int parsed_arg_cursor) { List<String> parsed_args = sp.getJVMArguments(); int i_bump = 0; for (int i = 0; i < nparamsIncludingSelf; i++) { if (i == selfIndex) continue; String one_param = parsed_args.get(parsed_arg_cursor++); int load_op = SignatureParser.asm_loadop(one_param); mv.visitVarInsn(load_op, i + i_bump); // TODO Need to get counting right here. P0 is "really" P1 if (i == 1 && forceCastParam0 != null) { mv.visitTypeInsn(CHECKCAST, forceCastParam0); } // if one_param is long or double, increment i_bump to account for the extra slot. i_bump += SignatureParser.width(one_param) - 1; } }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
/** * Generate a trivial init method./* w ww .jav a2 s .co m*/ * * @param cw * @param _super */ private static void simpleInitMethod(ManglingClassWriter cw, String _super) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, _super, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
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); /*/* w ww .ja v a 2s .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
private byte[] instantiateAbstractArrow(String name, List<String> parameters) { ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); /*/* w ww .j ava2s . c o m*/ * Special case extensions to plumb tuples * correctly in the face of generics instantiated * with tuple types. * * Except, recall that Arrow parameters are domain...;range * * if > 1 param then * unwrap = params * wrap = tuple params * else 1 param * if tuple * wrap = param * unwrap = untuple params * else * unwrap = param * wrap = null * * Use unwrapped parameters to generate the all-Objects case * for casting; check the generated signature against the input * to see if we are them. * */ 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 obj_sig = stringListToGeneric(ABSTRACT_ARROW, norm_obj_params_and_ret); String obj_intf_sig = stringListToGeneric(Naming.ARROW_TAG, norm_obj_params_and_ret); String wrapped_sig = stringListToGeneric(WRAPPED_ARROW, norm_params_and_ret); String typed_intf_sig = stringListToGeneric(Naming.ARROW_TAG, norm_params_and_ret); String unwrapped_apply_sig; if (parameters.size() == 2 && parameters.get(0).equals(Naming.INTERNAL_SNOWMAN)) unwrapped_apply_sig = arrowParamsToJVMsig(parameters.subList(1, 2)); else unwrapped_apply_sig = arrowParamsToJVMsig(flat_params_and_ret); String obj_apply_sig = arrowParamsToJVMsig(flat_obj_params_and_ret); String[] interfaces = new String[] { stringListToArrow(norm_params_and_ret) }; /* * Note that in the case of foo -> bar, * normalized = flattened, and tupled does not exist (is null). */ String typed_tupled_intf_sig = tupled_params_and_ret == null ? null : stringListToGeneric(Naming.ARROW_TAG, tupled_params_and_ret); String objectified_tupled_intf_sig = tupled_params_and_ret == null ? null : stringListToGeneric(Naming.ARROW_TAG, Useful.applyToAll(tupled_params_and_ret, toJLO)); boolean is_all_objects = norm_obj_params_and_ret.equals(norm_params_and_ret); String _super = is_all_objects ? "java/lang/Object" : obj_sig; cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_ABSTRACT, name, null, _super, interfaces); simpleInitMethod(cw, _super); /* */ if (!is_all_objects) { // implement method for the object version. // cast parameters, invoke this.apply on cast parameters, ARETURN // note cut and paste from apply below, work in progress. MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, obj_apply_sig, null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); // this int unwrapped_l = flat_params_and_ret.size(); for (int i = 0; i < unwrapped_l - 1; i++) { String t = flat_params_and_ret.get(i); if (!t.equals(Naming.INTERNAL_SNOWMAN) || unwrapped_l > 2) { mv.visitVarInsn(Opcodes.ALOAD, i + 1); // element // mv.visitTypeInsn(CHECKCAST, t); generalizedCastTo(mv, Naming.internalToType(t)); } } mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, unwrapped_apply_sig); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } // is instance method -- takes an Object { String sig = "(Ljava/lang/Object;)Z"; MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, IS_A, sig, null, null); Label fail = new Label(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.INSTANCEOF, Naming.ANY_TYPE_CLASS); mv.visitJumpInsn(Opcodes.IFEQ, fail); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.CHECKCAST, Naming.ANY_TYPE_CLASS); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, IS_A, "(" + Naming.internalToDesc(Naming.ANY_TYPE_CLASS) + ")Z"); mv.visitInsn(Opcodes.IRETURN); mv.visitLabel(fail); mv.visitIntInsn(BIPUSH, 0); mv.visitInsn(Opcodes.IRETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } // is instance method -- takes an Any { String sig = "(" + Naming.internalToDesc(Naming.ANY_TYPE_CLASS) + ")Z"; MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, IS_A, sig, null, null); Label fail = new Label(); //get RTTI to compare to mv.visitFieldInsn(GETSTATIC, name, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC); //get RTTI of object mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(INVOKEINTERFACE, Naming.ANY_TYPE_CLASS, Naming.RTTI_GETTER, "()" + Naming.RTTI_CONTAINER_DESC); // mv.visitJumpInsn(IFNONNULL, fail); mv.visitMethodInsn(INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG); //mv.visitIntInsn(BIPUSH, 0); mv.visitJumpInsn(Opcodes.IFEQ, fail); mv.visitIntInsn(BIPUSH, 1); mv.visitInsn(Opcodes.IRETURN); mv.visitLabel(fail); mv.visitIntInsn(BIPUSH, 0); mv.visitInsn(Opcodes.IRETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } // castTo { /* * If arg0 instanceof typed_intf_sig * return arg0 * arg0 = arg0.getWrappee() * if arg0 instanceof typed_intf_sig * return arg0 * new WrappedArrow * dup * push argo * init * return tos */ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CAST_TO, "(" + // Naming.internalToDesc(obj_intf_sig) "Ljava/lang/Object;" + ")" + Naming.internalToDesc(typed_intf_sig), null, null); Label not_instance1 = new Label(); Label not_instance2 = new Label(); // try bare instanceof mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig); mv.visitJumpInsn(Opcodes.IFEQ, not_instance1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.CHECKCAST, typed_intf_sig); mv.visitInsn(Opcodes.ARETURN); // unwrap mv.visitLabel(not_instance1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.CHECKCAST, obj_intf_sig); mv.visitMethodInsn(INVOKEINTERFACE, obj_intf_sig, getWrappee, "()" + Naming.internalToDesc(obj_intf_sig)); mv.visitVarInsn(Opcodes.ASTORE, 0); // try instanceof on unwrapped mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig); mv.visitJumpInsn(Opcodes.IFEQ, not_instance2); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.CHECKCAST, typed_intf_sig); mv.visitInsn(Opcodes.ARETURN); // wrap and return mv.visitLabel(not_instance2); mv.visitTypeInsn(NEW, wrapped_sig); mv.visitInsn(DUP); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, wrapped_sig, "<init>", "(" + Naming.internalToDesc(obj_intf_sig) + ")V"); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } if (typed_tupled_intf_sig != null) { /* * If arg0 instanceof typed_intf_sig * return arg0 * arg0 = arg0.getWrappee() * if arg0 instanceof typed_intf_sig * return arg0 * new WrappedArrow * dup * push argo * init * return tos */ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CAST_TO, "(" + Naming.internalToDesc(objectified_tupled_intf_sig) + ")" + Naming.internalToDesc(typed_intf_sig), null, null); Label not_instance1 = new Label(); Label not_instance2 = new Label(); // try bare instanceof mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig); mv.visitJumpInsn(Opcodes.IFEQ, not_instance1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ARETURN); // unwrap mv.visitLabel(not_instance1); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(INVOKEINTERFACE, objectified_tupled_intf_sig, getWrappee, "()" + Naming.internalToDesc(objectified_tupled_intf_sig)); mv.visitVarInsn(Opcodes.ASTORE, 0); // try instanceof on unwrapped mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig); mv.visitJumpInsn(Opcodes.IFEQ, not_instance2); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ARETURN); // wrap and return - untupled should be okay here, since it subtypes mv.visitLabel(not_instance2); mv.visitTypeInsn(NEW, wrapped_sig); mv.visitInsn(DUP); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, wrapped_sig, "<init>", "(" + Naming.internalToDesc(obj_intf_sig) + ")V"); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } // getWrappee { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getWrappee, "()" + Naming.internalToDesc(obj_intf_sig), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // return this } if (tupled_params_and_ret == null) { /* Single abstract method */ if (LOG_LOADS) System.err.println(name + ".apply" + unwrapped_apply_sig + " abstract for abstract"); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, Naming.APPLY_METHOD, unwrapped_apply_sig, null, null); mv.visitEnd(); } else { /* * Establish two circular forwarding methods; * the eventual implementer will break the cycle. * */ String tupled_apply_sig = arrowParamsToJVMsig(tupled_params_and_ret); { /* Given tupled args, extract, and invoke apply. */ if (LOG_LOADS) System.err.println(name + ".apply" + tupled_apply_sig + " abstract for abstract"); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, tupled_apply_sig, null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); // closure int unwrapped_l = flat_params_and_ret.size(); for (int i = 0; i < unwrapped_l - 1; i++) { String param = flat_params_and_ret.get(i); mv.visitVarInsn(Opcodes.ALOAD, 1); // tuple mv.visitMethodInsn(INVOKEINTERFACE, tupleType, TUPLE_TYPED_ELT_PFX + (Naming.TUPLE_ORIGIN + i), "()" + Naming.internalToDesc(param)); } mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, unwrapped_apply_sig); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } { /* Given untupled args, load, make a tuple, invoke apply. */ if (LOG_LOADS) System.err.println(name + ".apply" + unwrapped_apply_sig + " abstract for abstract"); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, unwrapped_apply_sig, null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); // closure int unwrapped_l = flat_params_and_ret.size(); for (int i = 0; i < unwrapped_l - 1; i++) { mv.visitVarInsn(Opcodes.ALOAD, i + 1); // element } List<String> tuple_elements = flat_params_and_ret.subList(0, unwrapped_l - 1); String make_sig = toJvmSig(tuple_elements, Naming.javaDescForTaggedFortressType(tupleType)); mv.visitMethodInsn(INVOKESTATIC, stringListToGeneric(CONCRETE_TUPLE, tuple_elements), "make", make_sig); mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, tupled_apply_sig); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); } } //RTTI comparison field final String final_name = name; ArrayList<InitializedStaticField> isf_list = new ArrayList<InitializedStaticField>(); if (!parameters.contains("java/lang/Object")) { isf_list.add(new InitializedStaticField.StaticForUsualRttiField(final_name, this)); } else { isf_list.add(new InitializedStaticField.StaticForJLOParameterizedRttiField(final_name)); } cw.visitEnd(); // //RTTI getter { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.RTTI_GETTER, "()" + Naming.RTTI_CONTAINER_DESC, null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, name, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } optionalStaticsAndClassInitForTO(isf_list, cw); return cw.toByteArray(); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
private static byte[] instantiateArrowRTTI(String name) { ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // Tuple,N$RTTIc int dollar_at = name.indexOf('$'); String stem_name = name.substring(0, dollar_at); String nstring = name.substring(Naming.ARROW_RTTI_TAG.length(), dollar_at); final int n = Integer.parseInt(nstring); String[] superInterfaces = null; cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC, name, null, Naming.ARROW_RTTI_CONTAINER_TYPE, superInterfaces); // init//from w w w . j ava 2 s . co m { String init_sig = InstantiatingClassloader.jvmSignatureForOnePlusNTypes("java/lang/Class", n, Naming.RTTI_CONTAINER_TYPE, "V"); MethodVisitor mv = cw.visitNoMangleMethod(ACC_PUBLIC, "<init>", init_sig, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // this mv.visitVarInsn(ALOAD, 1); // class // allocate and init array for next parameter int first_element = 2; // new array mv.visitLdcInsn(new Integer(n)); mv.visitTypeInsn(ANEWARRAY, Naming.RTTI_CONTAINER_TYPE); for (int i = 0; i < n; i++) { mv.visitInsn(DUP); mv.visitLdcInsn(new Integer(i)); mv.visitVarInsn(ALOAD, first_element + i); mv.visitInsn(AASTORE); } // invoke super.<init> mv.visitMethodInsn(INVOKESPECIAL, Naming.ARROW_RTTI_CONTAINER_TYPE, "<init>", "(Ljava/lang/Class;[" + Naming.RTTI_CONTAINER_DESC + ")V"); int pno = 2; // skip the java class parameter for (int i = Naming.STATIC_PARAMETER_ORIGIN; i < n + Naming.STATIC_PARAMETER_ORIGIN; i++) { String spn = "T" + i; // not yet this; sp.getKind(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, pno); mv.visitFieldInsn(PUTFIELD, name, spn, Naming.RTTI_CONTAINER_DESC); pno++; } voidEpilogue(mv); } // fields and getters for (int i = Naming.STATIC_PARAMETER_ORIGIN; i < n + Naming.STATIC_PARAMETER_ORIGIN; i++) { fieldAndGetterForStaticParameter(cw, stem_name, "T" + i, i); } // clinit -- part of the dictionary call // dictionary // factory // ought to create bogus xldata for tuples and arrows, instead we pass null emitDictionaryAndFactoryForGenericRTTIclass(cw, name, n, null); cw.visitEnd(); return cw.toByteArray(); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
private static byte[] instantiateAnyConcreteTuple(String dename, List<String> parameters) { /*/* w w w .j a va2 s . co m*/ * Single parameter, N, which is the arity of the tuple. * * extends Ljava/util/AbstractList; * implements LAnyTuple[\N\]; * int size() { return N; } * Object get(int n) { * if (n >= N || n < 0) { * throw new IndexOutOfBoundsException(); * } else { * // binary search tree returning o1 ... oN * } * } */ ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); final String super_type = "java/lang/Object"; final int n = Integer.parseInt(parameters.get(0)); final String any_tuple_n = ANY_TUPLE + Naming.LEFT_OXFORD + n + Naming.RIGHT_OXFORD; String[] superInterfaces = { any_tuple_n }; cw.visit(JVM_BYTECODE_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, dename, null, super_type, superInterfaces); simpleInitMethod(cw, super_type); { // size method MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "size", "()I", null, null); mv.visitCode(); mv.visitIntInsn(BIPUSH, n); mv.visitInsn(IRETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { // get method final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "(I)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); mv.visitIntInsn(BIPUSH, n); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l1); mv.visitVarInsn(ILOAD, 1); Label l2 = new Label(); mv.visitJumpInsn(IFGE, l2); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(NEW, "java/lang/IndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IndexOutOfBoundsException", "<init>", "()V"); mv.visitInsn(ATHROW); FnVoidVoid geti = new FnVoidVoid() { @Override public void apply() { mv.visitVarInsn(ILOAD, 1); } }; FnVoid<Integer> leaf = new FnVoid<Integer>() { @Override public void apply(Integer x) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEINTERFACE, any_tuple_n, TUPLE_OBJECT_ELT_PFX + (Naming.TUPLE_ORIGIN + x), UNTYPED_GETTER_SIG); mv.visitInsn(ARETURN); } }; visitBinaryTree(mv, 0, n - 1, l2, geti, leaf); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java
License:Open Source License
private static byte[] instantiateTupleRTTI(String name) { ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // Tuple,N$RTTIc int dollar_at = name.indexOf('$'); String stem_name = name.substring(0, dollar_at); String nstring = name.substring(Naming.TUPLE_RTTI_TAG.length(), dollar_at); final int n = Integer.parseInt(nstring); String[] superInterfaces = null; cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC, name, null, Naming.TUPLE_RTTI_CONTAINER_TYPE, superInterfaces); // init/*from w w w . j a v a2s.co m*/ { String init_sig = InstantiatingClassloader.jvmSignatureForOnePlusNTypes("java/lang/Class", n, Naming.RTTI_CONTAINER_TYPE, "V"); MethodVisitor mv = cw.visitNoMangleMethod(ACC_PUBLIC, "<init>", init_sig, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // this mv.visitVarInsn(ALOAD, 1); // class // allocate and init array for next parameter int first_element = 2; // new array mv.visitLdcInsn(new Integer(n)); mv.visitTypeInsn(ANEWARRAY, Naming.RTTI_CONTAINER_TYPE); for (int i = 0; i < n; i++) { mv.visitInsn(DUP); mv.visitLdcInsn(new Integer(i)); mv.visitVarInsn(ALOAD, first_element + i); mv.visitInsn(AASTORE); } // invoke super.<init> mv.visitMethodInsn(INVOKESPECIAL, Naming.TUPLE_RTTI_CONTAINER_TYPE, "<init>", "(Ljava/lang/Class;[" + Naming.RTTI_CONTAINER_DESC + ")V"); int pno = 2; // skip the java class parameter for (int i = Naming.STATIC_PARAMETER_ORIGIN; i < n + Naming.STATIC_PARAMETER_ORIGIN; i++) { String spn = "T" + i; // not yet this; sp.getKind(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, pno); mv.visitFieldInsn(PUTFIELD, name, spn, Naming.RTTI_CONTAINER_DESC); pno++; } voidEpilogue(mv); } // fields and getters for (int i = Naming.STATIC_PARAMETER_ORIGIN; i < n + Naming.STATIC_PARAMETER_ORIGIN; i++) { fieldAndGetterForStaticParameter(cw, stem_name, "T" + i, i); } // clinit -- part of the dictionary call // dictionary // factory // ought to create bogus xldata for tuples and arrows, instead we pass null emitDictionaryAndFactoryForGenericRTTIclass(cw, name, n, null); cw.visitEnd(); return cw.toByteArray(); }