Skip to content

Commit

Permalink
Throw an NYI CompileException when a static interface method is invoked.
Browse files Browse the repository at this point in the history
  • Loading branch information
aunkrig committed Dec 19, 2019
1 parent 1f83ff1 commit efd3884
Showing 1 changed file with 40 additions and 9 deletions.
49 changes: 40 additions & 9 deletions janino/src/main/java/org/codehaus/janino/UnitCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -11882,23 +11882,54 @@ interface Compilable { void compile() throws CompileException; }
*/
private void
invoke(Locatable locatable, IMethod iMethod) throws CompileException {
if (iMethod.getDeclaringIClass().isInterface() && !iMethod.isStatic()) {

final IClass declaringIClass = iMethod.getDeclaringIClass();

if (iMethod.isStatic()) {

// Static class method, or a static interface method (a Java 8 feature).
final ClassFile classFile = this.getCodeContext().getClassFile();
if (
declaringIClass.isInterface()
&& classFile.getMajorVersion() <= ClassFile.MAJOR_VERSION_JDK_1_7
&& classFile.getMinorVersion() <= ClassFile.MINOR_VERSION_JDK_1_7
) {
// INVOKESTATIC InterfaceMethodRef only allowed since Java 8 class file format.
this.compileError(
"Invocation of static interface methods NYI",
locatable.getLocation()
);
}

this.writeOpcode(locatable, Opcode.INVOKESTATIC);
this.writeConstantMethodrefInfo(
declaringIClass.getDescriptor(), // classFD
iMethod.getName(), // methodName
iMethod.getDescriptor() // methodMD
);
} else
if (declaringIClass.isInterface()) {

// A non-static interface method.
this.writeOpcode(locatable, Opcode.INVOKEINTERFACE);
this.writeConstantInterfaceMethodrefInfo(
iMethod.getDeclaringIClass().getDescriptor(), // classFD
iMethod.getName(), // methodName
iMethod.getDescriptor() // methodMD
declaringIClass.getDescriptor(), // classFD
iMethod.getName(), // methodName
iMethod.getDescriptor() // methodMD
);
int count = 1;
for (IClass pt : iMethod.getParameterTypes()) count += Descriptor.size(pt.getDescriptor());
this.writeByte(count);
this.writeByte(0);
} else {
this.writeOpcode(locatable, iMethod.isStatic() ? Opcode.INVOKESTATIC : Opcode.INVOKEVIRTUAL);
} else
{

// A non-static class mathod.
this.writeOpcode(locatable, Opcode.INVOKEVIRTUAL);
this.writeConstantMethodrefInfo(
iMethod.getDeclaringIClass().getDescriptor(), // classFD
iMethod.getName(), // methodName
iMethod.getDescriptor() // methodMD
declaringIClass.getDescriptor(), // classFD
iMethod.getName(), // methodName
iMethod.getDescriptor() // methodMD
);
}
}
Expand Down

0 comments on commit efd3884

Please sign in to comment.