Search in sources :

Example 1 with DynamicMethod

use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod in project ceylon by eclipse.

the class ClassWriter method writeBootstrapMethods.

/**
 * Write "bootstrapMethods" attribute.
 */
void writeBootstrapMethods() {
    int alenIdx = writeAttr(names.BootstrapMethods);
    databuf.appendChar(bootstrapMethods.size());
    for (Map.Entry<DynamicMethod, MethodHandle> entry : bootstrapMethods.entrySet()) {
        DynamicMethod dmeth = entry.getKey();
        DynamicMethodSymbol dsym = (DynamicMethodSymbol) dmeth.baseSymbol();
        // write BSM handle
        databuf.appendChar(pool.get(entry.getValue()));
        // write static args length
        databuf.appendChar(dsym.staticArgs.length);
        // write static args array
        Object[] uniqueArgs = dmeth.uniqueStaticArgs;
        for (Object o : uniqueArgs) {
            databuf.appendChar(pool.get(o));
        }
    }
    endAttr(alenIdx);
}
Also used : JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) FileObject(org.eclipse.ceylon.javax.tools.FileObject) BaseFileObject(org.eclipse.ceylon.langtools.tools.javac.file.BaseFileObject) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) DynamicMethod(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod) MethodHandle(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle)

Example 2 with DynamicMethod

use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod in project ceylon by eclipse.

the class ClassWriter method writeClassFile.

/**
 * Write class `c' to outstream `out'.
 */
public void writeClassFile(OutputStream out, ClassSymbol c) throws IOException, PoolOverflow, StringOverflow {
    Assert.check((c.flags() & COMPOUND) == 0);
    databuf.reset();
    poolbuf.reset();
    signatureGen.reset();
    pool = c.pool;
    innerClasses = null;
    innerClassesQueue = null;
    bootstrapMethods = new LinkedHashMap<DynamicMethod, MethodHandle>();
    Type supertype = types.supertype(c.type);
    List<Type> interfaces = types.interfaces(c.type);
    List<Type> typarams = c.type.getTypeArguments();
    int flags = adjustFlags(c.flags() & ~DEFAULT);
    if ((flags & PROTECTED) != 0)
        flags |= PUBLIC;
    flags = flags & ClassFlags & ~STRICTFP;
    if ((flags & INTERFACE) == 0)
        flags |= ACC_SUPER;
    if (c.isInner() && c.name.isEmpty())
        flags &= ~FINAL;
    if (dumpClassModifiers) {
        PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
        pw.println();
        pw.println("CLASSFILE  " + c.getQualifiedName());
        pw.println("---" + flagNames(flags));
    }
    databuf.appendChar(flags);
    databuf.appendChar(pool.put(c));
    databuf.appendChar(supertype.hasTag(CLASS) ? pool.put(supertype.tsym) : 0);
    databuf.appendChar(interfaces.length());
    for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail) databuf.appendChar(pool.put(l.head.tsym));
    int fieldsCount = 0;
    int methodsCount = 0;
    for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) {
        switch(e.sym.kind) {
            case VAR:
                fieldsCount++;
                break;
            case MTH:
                if ((e.sym.flags() & HYPOTHETICAL) == 0)
                    methodsCount++;
                break;
            case TYP:
                enterInner((ClassSymbol) e.sym);
                break;
            default:
                Assert.error();
        }
    }
    if (c.trans_local != null) {
        for (ClassSymbol local : c.trans_local) {
            enterInner(local);
        }
    }
    databuf.appendChar(fieldsCount);
    writeFields(c.members().elems);
    databuf.appendChar(methodsCount);
    writeMethods(c.members().elems);
    int acountIdx = beginAttrs();
    int acount = 0;
    boolean sigReq = typarams.length() != 0 || supertype.allparams().length() != 0;
    for (List<Type> l = interfaces; !sigReq && l.nonEmpty(); l = l.tail) sigReq = l.head.allparams().length() != 0;
    if (sigReq) {
        Assert.check(source.allowGenerics());
        int alenIdx = writeAttr(names.Signature);
        if (typarams.length() != 0)
            signatureGen.assembleParamsSig(typarams);
        signatureGen.assembleSig(supertype);
        for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail) signatureGen.assembleSig(l.head);
        databuf.appendChar(pool.put(signatureGen.toName()));
        signatureGen.reset();
        endAttr(alenIdx);
        acount++;
    }
    if (c.sourcefile != null && emitSourceFile) {
        int alenIdx = writeAttr(names.SourceFile);
        // WHM 6/29/1999: Strip file path prefix.  We do it here at
        // the last possible moment because the sourcefile may be used
        // elsewhere in error diagnostics. Fixes 4241573.
        // databuf.appendChar(c.pool.put(c.sourcefile));
        String simpleName = BaseFileObject.getSimpleName(c.sourcefile);
        databuf.appendChar(c.pool.put(names.fromString(simpleName)));
        endAttr(alenIdx);
        acount++;
    }
    if (genCrt) {
        // Append SourceID attribute
        int alenIdx = writeAttr(names.SourceID);
        databuf.appendChar(c.pool.put(names.fromString(Long.toString(getLastModified(c.sourcefile)))));
        endAttr(alenIdx);
        acount++;
        // Append CompilationID attribute
        alenIdx = writeAttr(names.CompilationID);
        databuf.appendChar(c.pool.put(names.fromString(Long.toString(System.currentTimeMillis()))));
        endAttr(alenIdx);
        acount++;
    }
    acount += writeFlagAttrs(c.flags());
    acount += writeJavaAnnotations(c.getRawAttributes());
    acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
    acount += writeEnclosingMethodAttribute(c);
    acount += writeExtraClassAttributes(c);
    poolbuf.appendInt(JAVA_MAGIC);
    poolbuf.appendChar(target.minorVersion);
    poolbuf.appendChar(target.majorVersion);
    writePool(c.pool);
    if (innerClasses != null) {
        writeInnerClasses();
        acount++;
    }
    if (!bootstrapMethods.isEmpty()) {
        writeBootstrapMethods();
        acount++;
    }
    endAttrs(acountIdx, acount);
    poolbuf.appendBytes(databuf.elems, 0, databuf.length);
    out.write(poolbuf.elems, 0, poolbuf.length);
    // to conserve space
    pool = c.pool = null;
}
Also used : UninitializedType(org.eclipse.ceylon.langtools.tools.javac.jvm.UninitializedType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UniqueType(org.eclipse.ceylon.langtools.tools.javac.code.Types.UniqueType) DynamicMethod(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod) MethodHandle(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle)

Example 3 with DynamicMethod

use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod in project ceylon by eclipse.

the class ClassWriter method writePool.

/**
 * Write constant pool to pool buffer.
 *  Note: during writing, constant pool
 *  might grow since some parts of constants still need to be entered.
 */
void writePool(Pool pool) throws PoolOverflow, StringOverflow {
    int poolCountIdx = poolbuf.length;
    poolbuf.appendChar(0);
    int i = 1;
    while (i < pool.pp) {
        Object value = pool.pool[i];
        Assert.checkNonNull(value);
        if (value instanceof Method || value instanceof Variable)
            value = ((DelegatedSymbol) value).getUnderlyingSymbol();
        if (value instanceof MethodSymbol) {
            MethodSymbol m = (MethodSymbol) value;
            if (!m.isDynamic()) {
                poolbuf.appendByte((m.owner.flags() & INTERFACE) != 0 ? CONSTANT_InterfaceMethodref : CONSTANT_Methodref);
                poolbuf.appendChar(pool.put(m.owner));
                poolbuf.appendChar(pool.put(nameType(m)));
            } else {
                // invokedynamic
                DynamicMethodSymbol dynSym = (DynamicMethodSymbol) m;
                MethodHandle handle = new MethodHandle(dynSym.bsmKind, dynSym.bsm, types);
                DynamicMethod dynMeth = new DynamicMethod(dynSym, types);
                bootstrapMethods.put(dynMeth, handle);
                // init cp entries
                pool.put(names.BootstrapMethods);
                pool.put(handle);
                for (Object staticArg : dynSym.staticArgs) {
                    pool.put(staticArg);
                }
                poolbuf.appendByte(CONSTANT_InvokeDynamic);
                poolbuf.appendChar(bootstrapMethods.size() - 1);
                poolbuf.appendChar(pool.put(nameType(dynSym)));
            }
        } else if (value instanceof VarSymbol) {
            VarSymbol v = (VarSymbol) value;
            poolbuf.appendByte(CONSTANT_Fieldref);
            poolbuf.appendChar(pool.put(v.owner));
            poolbuf.appendChar(pool.put(nameType(v)));
        } else if (value instanceof Name) {
            poolbuf.appendByte(CONSTANT_Utf8);
            byte[] bs = ((Name) value).toUtf();
            poolbuf.appendChar(bs.length);
            poolbuf.appendBytes(bs, 0, bs.length);
            if (bs.length > Pool.MAX_STRING_LENGTH)
                throw new StringOverflow(value.toString());
        } else if (value instanceof ClassSymbol) {
            ClassSymbol c = (ClassSymbol) value;
            if (c.owner.kind == TYP)
                pool.put(c.owner);
            poolbuf.appendByte(CONSTANT_Class);
            if (c.type.hasTag(ARRAY)) {
                poolbuf.appendChar(pool.put(typeSig(c.type)));
            } else {
                poolbuf.appendChar(pool.put(names.fromUtf(externalize(c.flatname))));
                enterInner(c);
            }
        } else if (value instanceof NameAndType) {
            NameAndType nt = (NameAndType) value;
            poolbuf.appendByte(CONSTANT_NameandType);
            poolbuf.appendChar(pool.put(nt.name));
            poolbuf.appendChar(pool.put(typeSig(nt.uniqueType.type)));
        } else if (value instanceof Integer) {
            poolbuf.appendByte(CONSTANT_Integer);
            poolbuf.appendInt(((Integer) value).intValue());
        } else if (value instanceof Long) {
            poolbuf.appendByte(CONSTANT_Long);
            poolbuf.appendLong(((Long) value).longValue());
            i++;
        } else if (value instanceof Float) {
            poolbuf.appendByte(CONSTANT_Float);
            poolbuf.appendFloat(((Float) value).floatValue());
        } else if (value instanceof Double) {
            poolbuf.appendByte(CONSTANT_Double);
            poolbuf.appendDouble(((Double) value).doubleValue());
            i++;
        } else if (value instanceof String) {
            poolbuf.appendByte(CONSTANT_String);
            poolbuf.appendChar(pool.put(names.fromString((String) value)));
        } else if (value instanceof UniqueType) {
            Type type = ((UniqueType) value).type;
            if (type instanceof MethodType) {
                poolbuf.appendByte(CONSTANT_MethodType);
                poolbuf.appendChar(pool.put(typeSig((MethodType) type)));
            } else {
                if (type.hasTag(CLASS))
                    enterInner((ClassSymbol) type.tsym);
                poolbuf.appendByte(CONSTANT_Class);
                poolbuf.appendChar(pool.put(xClassName(type)));
            }
        } else if (value instanceof MethodHandle) {
            MethodHandle ref = (MethodHandle) value;
            poolbuf.appendByte(CONSTANT_MethodHandle);
            poolbuf.appendByte(ref.refKind);
            poolbuf.appendChar(pool.put(ref.refSym));
        } else {
            Assert.error("writePool " + value);
        }
        i++;
    }
    if (pool.pp > Pool.MAX_ENTRIES)
        throw new PoolOverflow();
    putChar(poolbuf, poolCountIdx, pool.pp);
}
Also used : Variable(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.Variable) Method(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.Method) DynamicMethod(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod) DynamicMethod(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod) UniqueType(org.eclipse.ceylon.langtools.tools.javac.code.Types.UniqueType) UninitializedType(org.eclipse.ceylon.langtools.tools.javac.jvm.UninitializedType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UniqueType(org.eclipse.ceylon.langtools.tools.javac.code.Types.UniqueType) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) FileObject(org.eclipse.ceylon.javax.tools.FileObject) BaseFileObject(org.eclipse.ceylon.langtools.tools.javac.file.BaseFileObject) MethodHandle(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle)

Aggregations

DynamicMethod (org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.DynamicMethod)3 MethodHandle (org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle)3 FileObject (org.eclipse.ceylon.javax.tools.FileObject)2 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)2 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)2 UniqueType (org.eclipse.ceylon.langtools.tools.javac.code.Types.UniqueType)2 BaseFileObject (org.eclipse.ceylon.langtools.tools.javac.file.BaseFileObject)2 UninitializedType (org.eclipse.ceylon.langtools.tools.javac.jvm.UninitializedType)2 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Method (org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.Method)1 Variable (org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.Variable)1