Example #1
0
 /**
  * Produce a string form of this member name. For types, it is simply the type's own string (as
  * reported by {@code toString}). For fields, it is {@code "DeclaringClass.name/type"}. For
  * methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}. If the declaring
  * class is null, the prefix {@code "DeclaringClass."} is omitted. If the member is unresolved, a
  * prefix {@code "*."} is prepended.
  */
 @Override
 public String toString() {
   if (isType()) return type.toString(); // class java.lang.String
   // else it is a field, method, or constructor
   StringBuilder buf = new StringBuilder();
   if (getDeclaringClass() != null) {
     buf.append(getName(clazz));
     buf.append('.');
   }
   String name = getName();
   buf.append(name == null ? "*" : name);
   Object type = getType();
   if (!isInvocable()) {
     buf.append('/');
     buf.append(type == null ? "*" : getName(type));
   } else {
     buf.append(type == null ? "(*)*" : getName(type));
   }
   /*
   buf.append('/');
   // key: Public, private, pRotected, sTatic, Final, sYnchronized,
   // transient/Varargs, native, (interface), abstract, sTrict, sYnthetic,
   // (annotation), Enum, (unused)
   final String FIELD_MOD_CHARS  = "PprTF?vt????Y?E?";
   final String METHOD_MOD_CHARS = "PprTFybVn?atY???";
   String modChars = (isInvocable() ? METHOD_MOD_CHARS : FIELD_MOD_CHARS);
   for (int i = 0; i < modChars.length(); i++) {
       if ((flags & (1 << i)) != 0) {
           char mc = modChars.charAt(i);
           if (mc != '?')
               buf.append(mc);
       }
   }
    */
   return buf.toString();
 }
  private static LambdaForm makePreparedFieldLambdaForm(
      byte formOp, boolean isVolatile, int ftypeKind) {
    boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
    boolean isStatic = (formOp >= AF_GETSTATIC);
    boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
    boolean needsCast = (ftypeKind == FT_CHECKED_REF);
    Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
    Class<?> ft = fw.primitiveType();
    assert (ftypeKind(needsCast ? String.class : ft) == ftypeKind);

    // getObject, putIntVolatile, etc.
    StringBuilder nameBuilder = new StringBuilder();
    if (isGetter) {
      nameBuilder.append("get");
    } else {
      nameBuilder.append("put");
    }
    nameBuilder.append(fw.primitiveSimpleName());
    nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
    if (isVolatile) {
      nameBuilder.append("Volatile");
    }

    MethodType linkerType;
    if (isGetter) linkerType = MethodType.methodType(ft, Object.class, long.class);
    else linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
    MemberName linker =
        new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
    try {
      linker =
          IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
    } catch (ReflectiveOperationException ex) {
      throw newInternalError(ex);
    }

    // What is the external type of the lambda form?
    MethodType mtype;
    if (isGetter) mtype = MethodType.methodType(ft);
    else mtype = MethodType.methodType(void.class, ft);
    mtype = mtype.basicType(); // erase short to int, etc.
    if (!isStatic) mtype = mtype.insertParameterTypes(0, Object.class);
    final int DMH_THIS = 0;
    final int ARG_BASE = 1;
    final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
    // if this is for non-static access, the base pointer is stored at this index:
    final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
    // if this is for write access, the value to be written is stored at this index:
    final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
    int nameCursor = ARG_LIMIT;
    final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
    final int F_OFFSET = nameCursor++; // Either static offset or field offset.
    final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
    final int INIT_BAR = (needsInit ? nameCursor++ : -1);
    final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
    final int LINKER_CALL = nameCursor++;
    final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
    final int RESULT = nameCursor - 1; // either the call or the cast
    Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
    if (needsInit) names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
    if (needsCast && !isGetter)
      names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
    Object[] outArgs = new Object[1 + linkerType.parameterCount()];
    assert (outArgs.length == (isGetter ? 3 : 4));
    outArgs[0] = UNSAFE;
    if (isStatic) {
      outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
      outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
    } else {
      outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
      outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]);
    }
    if (!isGetter) {
      outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
    }
    for (Object a : outArgs) assert (a != null);
    names[LINKER_CALL] = new Name(linker, outArgs);
    if (needsCast && isGetter)
      names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
    for (Name n : names) assert (n != null);
    // add some detail to the lambdaForm debugname,
    // significant only for debugging
    if (isStatic) {
      nameBuilder.append("Static");
    } else {
      nameBuilder.append("Field");
    }
    if (needsCast) nameBuilder.append("Cast");
    if (needsInit) nameBuilder.append("Init");
    return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
  }