use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle 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);
}
use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle 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;
}
use of org.eclipse.ceylon.langtools.tools.javac.jvm.Pool.MethodHandle 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);
}
Aggregations