Skip to content

Commit d336748

Browse files
authored
Merge pull request #8 from cl4es/serialization_hostile
SerializationHostileMethod
2 parents 3aaf246 + 1ce5360 commit d336748

File tree

1 file changed

+48
-43
lines changed

1 file changed

+48
-43
lines changed

src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,6 @@
6969
*/
7070
/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
7171
private static final String LAMBDA_INSTANCE_FIELD = "LAMBDA_INSTANCE$";
72-
73-
// Serialization support
74-
private static final ClassDesc CD_SerializedLambda = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/SerializedLambda;");
75-
private static final ClassDesc CD_NotSerializableException = ReferenceClassDescImpl.ofValidated("Ljava/io/NotSerializableException;");
76-
private static final ClassDesc CD_ObjectOutputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectOutputStream;");
77-
private static final ClassDesc CD_ObjectInputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectInputStream;");
78-
private static final MethodTypeDesc MTD_Object = MethodTypeDescImpl.ofValidated(CD_Object);
79-
private static final MethodTypeDesc MTD_void_ObjectOutputStream = MethodTypeDescImpl.ofValidated(CD_void, CD_ObjectOutputStream);
80-
private static final MethodTypeDesc MTD_void_ObjectInputStream = MethodTypeDescImpl.ofValidated(CD_void, CD_ObjectInputStream);
81-
82-
private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
83-
private static final String NAME_METHOD_READ_OBJECT = "readObject";
84-
private static final String NAME_METHOD_WRITE_OBJECT = "writeObject";
85-
86-
private static final MethodTypeDesc MTD_CTOR_SERIALIZED_LAMBDA = MethodTypeDescImpl.ofValidated(CD_void,
87-
CD_Class, CD_String, CD_String, CD_String, CD_int, CD_String, CD_String, CD_String, CD_String, ReferenceClassDescImpl.ofValidated("[Ljava/lang/Object;"));
88-
89-
private static final MethodTypeDesc MTD_CTOR_NOT_SERIALIZABLE_EXCEPTION = MethodTypeDescImpl.ofValidated(CD_void, CD_String);
90-
9172
private static final String[] EMPTY_STRING_ARRAY = new String[0];
9273
private static final ClassDesc[] EMPTY_CLASSDESC_ARRAY = ConstantUtils.EMPTY_CLASSDESC;
9374

@@ -440,15 +421,35 @@ public void accept(CodeBuilder cob) {
440421
}));
441422
}
442423

424+
private static class SerializationSupport {
425+
// Serialization support
426+
private static final ClassDesc CD_SerializedLambda = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/SerializedLambda;");
427+
private static final ClassDesc CD_ObjectOutputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectOutputStream;");
428+
private static final ClassDesc CD_ObjectInputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectInputStream;");
429+
private static final MethodTypeDesc MTD_Object = MethodTypeDescImpl.ofValidated(CD_Object);
430+
private static final MethodTypeDesc MTD_void_ObjectOutputStream = MethodTypeDescImpl.ofValidated(CD_void, CD_ObjectOutputStream);
431+
private static final MethodTypeDesc MTD_void_ObjectInputStream = MethodTypeDescImpl.ofValidated(CD_void, CD_ObjectInputStream);
432+
433+
private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
434+
private static final String NAME_METHOD_READ_OBJECT = "readObject";
435+
private static final String NAME_METHOD_WRITE_OBJECT = "writeObject";
436+
437+
static final ClassDesc CD_NotSerializableException = ReferenceClassDescImpl.ofValidated("Ljava/io/NotSerializableException;");
438+
static final MethodTypeDesc MTD_CTOR_NOT_SERIALIZABLE_EXCEPTION = MethodTypeDescImpl.ofValidated(CD_void, CD_String);
439+
static final MethodTypeDesc MTD_CTOR_SERIALIZED_LAMBDA = MethodTypeDescImpl.ofValidated(CD_void,
440+
CD_Class, CD_String, CD_String, CD_String, CD_int, CD_String, CD_String, CD_String, CD_String, ReferenceClassDescImpl.ofValidated("[Ljava/lang/Object;"));
441+
442+
}
443+
443444
/**
444445
* Generate a writeReplace method that supports serialization
445446
*/
446447
private void generateSerializationFriendlyMethods(ClassBuilder clb) {
447-
clb.withMethod(NAME_METHOD_WRITE_REPLACE, MTD_Object, ACC_PRIVATE | ACC_FINAL,
448+
clb.withMethod(SerializationSupport.NAME_METHOD_WRITE_REPLACE, SerializationSupport.MTD_Object, ACC_PRIVATE | ACC_FINAL,
448449
new MethodBody(new Consumer<CodeBuilder>() {
449450
@Override
450451
public void accept(CodeBuilder cob) {
451-
cob.new_(CD_SerializedLambda)
452+
cob.new_(SerializationSupport.CD_SerializedLambda)
452453
.dup()
453454
.ldc(classDesc(targetClass))
454455
.ldc(factoryType.returnType().getName().replace('.', '/'))
@@ -469,39 +470,43 @@ public void accept(CodeBuilder cob) {
469470
TypeConvertingMethodAdapter.boxIfTypePrimitive(cob, TypeKind.from(argDescs[i]));
470471
cob.aastore();
471472
}
472-
cob.invokespecial(CD_SerializedLambda, INIT_NAME, MTD_CTOR_SERIALIZED_LAMBDA)
473+
cob.invokespecial(SerializationSupport.CD_SerializedLambda, INIT_NAME,
474+
SerializationSupport.MTD_CTOR_SERIALIZED_LAMBDA)
473475
.areturn();
474476
}
475477
}));
476478
}
477479

478-
private static final Consumer<MethodBuilder> NOT_SERIALIZABLE_METHOD = new Consumer<MethodBuilder>() {
479-
@Override
480-
public void accept(MethodBuilder mb) {
481-
ConstantPoolBuilder cp = mb.constantPool();
482-
ClassEntry nseCE = cp.classEntry(CD_NotSerializableException);
483-
mb.with(ExceptionsAttribute.of(nseCE))
484-
.withCode(new Consumer<CodeBuilder>(){
485-
@Override
486-
public void accept(CodeBuilder cob) {
487-
cob.new_(nseCE)
488-
.dup()
489-
.ldc("Non-serializable lambda")
490-
.invokespecial(cp.methodRefEntry(nseCE, cp.nameAndTypeEntry(INIT_NAME, MTD_CTOR_NOT_SERIALIZABLE_EXCEPTION)))
491-
.athrow();
492-
}
493-
});
494-
}
495-
};
496-
497480
/**
498481
* Generate a readObject/writeObject method that is hostile to serialization
499482
*/
500483
private void generateSerializationHostileMethods(ClassBuilder clb) {
501-
clb.withMethod(NAME_METHOD_WRITE_OBJECT, MTD_void_ObjectOutputStream, ACC_PRIVATE + ACC_FINAL, NOT_SERIALIZABLE_METHOD);
502-
clb.withMethod(NAME_METHOD_READ_OBJECT, MTD_void_ObjectInputStream, ACC_PRIVATE + ACC_FINAL, NOT_SERIALIZABLE_METHOD);
484+
var hostileMethod = new Consumer<MethodBuilder>() {
485+
@Override
486+
public void accept(MethodBuilder mb) {
487+
ConstantPoolBuilder cp = mb.constantPool();
488+
ClassEntry nseCE = cp.classEntry(SerializationSupport.CD_NotSerializableException);
489+
mb.with(ExceptionsAttribute.of(nseCE))
490+
.withCode(new Consumer<CodeBuilder>() {
491+
@Override
492+
public void accept(CodeBuilder cob) {
493+
cob.new_(nseCE)
494+
.dup()
495+
.ldc("Non-serializable lambda")
496+
.invokespecial(cp.methodRefEntry(nseCE, cp.nameAndTypeEntry(INIT_NAME,
497+
SerializationSupport.MTD_CTOR_NOT_SERIALIZABLE_EXCEPTION)))
498+
.athrow();
499+
}
500+
});
501+
}
502+
};
503+
clb.withMethod(SerializationSupport.NAME_METHOD_WRITE_OBJECT, SerializationSupport.MTD_void_ObjectOutputStream,
504+
ACC_PRIVATE + ACC_FINAL, hostileMethod);
505+
clb.withMethod(SerializationSupport.NAME_METHOD_READ_OBJECT, SerializationSupport.MTD_void_ObjectInputStream,
506+
ACC_PRIVATE + ACC_FINAL, hostileMethod);
503507
}
504508

509+
505510
/**
506511
* This method generates a method body which calls the lambda implementation
507512
* method, converting arguments, as needed.

0 commit comments

Comments
 (0)