mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8335935: Chained builders not sending transformed models to next transforms
Reviewed-by: asotona
This commit is contained in:
parent
242f1133f8
commit
cad68e06ec
10 changed files with 196 additions and 124 deletions
|
@ -86,7 +86,7 @@ import java.lang.classfile.instruction.TypeCheckInstruction;
|
|||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static jdk.internal.classfile.impl.BytecodeHelpers.handleDescToHandleInfo;
|
||||
import jdk.internal.classfile.impl.TransformingCodeBuilder;
|
||||
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
|
||||
/**
|
||||
|
@ -192,7 +192,7 @@ public sealed interface CodeBuilder
|
|||
default CodeBuilder transforming(CodeTransform transform, Consumer<CodeBuilder> handler) {
|
||||
var resolved = transform.resolve(this);
|
||||
resolved.startHandler().run();
|
||||
handler.accept(new TransformingCodeBuilder(this, resolved.consumer()));
|
||||
handler.accept(new ChainedCodeBuilder(this, resolved.consumer()));
|
||||
resolved.endHandler().run();
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -51,13 +51,13 @@ public final class BlockCodeBuilderImpl
|
|||
|
||||
public void start() {
|
||||
topLocal = topLocal(parent);
|
||||
terminalMaxLocals = topLocal(terminal);
|
||||
terminal.with((LabelTarget) startLabel);
|
||||
terminalMaxLocals = terminal.curTopLocal();
|
||||
parent.with((LabelTarget) startLabel);
|
||||
}
|
||||
|
||||
public void end() {
|
||||
terminal.with((LabelTarget) endLabel);
|
||||
if (terminalMaxLocals != topLocal(terminal)) {
|
||||
parent.with((LabelTarget) endLabel);
|
||||
if (terminalMaxLocals != terminal.curTopLocal()) {
|
||||
throw new IllegalStateException("Interference in local variable slot management");
|
||||
}
|
||||
}
|
||||
|
@ -73,10 +73,8 @@ public final class BlockCodeBuilderImpl
|
|||
private int topLocal(CodeBuilder parent) {
|
||||
return switch (parent) {
|
||||
case BlockCodeBuilderImpl b -> b.topLocal;
|
||||
case ChainedCodeBuilder b -> topLocal(b.terminal);
|
||||
case DirectCodeBuilder b -> b.curTopLocal();
|
||||
case BufferedCodeBuilder b -> b.curTopLocal();
|
||||
case TransformingCodeBuilder b -> topLocal(b.delegate);
|
||||
case ChainedCodeBuilder b -> b.terminal.curTopLocal();
|
||||
case TerminalCodeBuilder b -> b.curTopLocal();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -43,7 +43,7 @@ import java.util.Optional;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
public final class BufferedCodeBuilder
|
||||
implements TerminalCodeBuilder, LabelContext {
|
||||
implements TerminalCodeBuilder {
|
||||
private final SplitConstantPool constantPool;
|
||||
private final ClassFileImpl context;
|
||||
private final List<CodeElement> elements = new ArrayList<>();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -33,13 +33,11 @@ import java.lang.classfile.constantpool.Utf8Entry;
|
|||
|
||||
public final class ChainedClassBuilder
|
||||
implements ClassBuilder, Consumer<ClassElement> {
|
||||
private final ClassBuilder downstream;
|
||||
private final DirectClassBuilder terminal;
|
||||
private final Consumer<ClassElement> consumer;
|
||||
|
||||
public ChainedClassBuilder(ClassBuilder downstream,
|
||||
Consumer<ClassElement> consumer) {
|
||||
this.downstream = downstream;
|
||||
this.consumer = consumer;
|
||||
this.terminal = switch (downstream) {
|
||||
case ChainedClassBuilder cb -> cb.terminal;
|
||||
|
@ -60,10 +58,11 @@ public final class ChainedClassBuilder
|
|||
|
||||
@Override
|
||||
public ClassBuilder withField(Utf8Entry name, Utf8Entry descriptor, Consumer<? super FieldBuilder> handler) {
|
||||
return downstream.with(new BufferedFieldBuilder(terminal.constantPool, terminal.context,
|
||||
consumer.accept(new BufferedFieldBuilder(terminal.constantPool, terminal.context,
|
||||
name, descriptor, null)
|
||||
.run(handler)
|
||||
.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,16 +71,18 @@ public final class ChainedClassBuilder
|
|||
field.fieldName(), field.fieldType(),
|
||||
field);
|
||||
builder.transform(field, transform);
|
||||
return downstream.with(builder.toModel());
|
||||
consumer.accept(builder.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassBuilder withMethod(Utf8Entry name, Utf8Entry descriptor, int flags,
|
||||
Consumer<? super MethodBuilder> handler) {
|
||||
return downstream.with(new BufferedMethodBuilder(terminal.constantPool, terminal.context,
|
||||
consumer.accept(new BufferedMethodBuilder(terminal.constantPool, terminal.context,
|
||||
name, descriptor, null)
|
||||
.run(handler)
|
||||
.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,7 +90,8 @@ public final class ChainedClassBuilder
|
|||
BufferedMethodBuilder builder = new BufferedMethodBuilder(terminal.constantPool, terminal.context,
|
||||
method.methodName(), method.methodType(), method);
|
||||
builder.transform(method, transform);
|
||||
return downstream.with(builder.toModel());
|
||||
consumer.accept(builder.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -36,13 +36,11 @@ import java.lang.classfile.MethodModel;
|
|||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
|
||||
public final class ChainedMethodBuilder implements MethodBuilder {
|
||||
final MethodBuilder downstream;
|
||||
final TerminalMethodBuilder terminal;
|
||||
final Consumer<MethodElement> consumer;
|
||||
|
||||
public ChainedMethodBuilder(MethodBuilder downstream,
|
||||
Consumer<MethodElement> consumer) {
|
||||
this.downstream = downstream;
|
||||
this.consumer = consumer;
|
||||
this.terminal = switch (downstream) {
|
||||
case ChainedMethodBuilder cb -> cb.terminal;
|
||||
|
@ -58,16 +56,18 @@ public final class ChainedMethodBuilder implements MethodBuilder {
|
|||
|
||||
@Override
|
||||
public MethodBuilder withCode(Consumer<? super CodeBuilder> handler) {
|
||||
return downstream.with(terminal.bufferedCodeBuilder(null)
|
||||
consumer.accept(terminal.bufferedCodeBuilder(null)
|
||||
.run(handler)
|
||||
.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodBuilder transformCode(CodeModel code, CodeTransform transform) {
|
||||
BufferedCodeBuilder builder = terminal.bufferedCodeBuilder(code);
|
||||
builder.transform(code, transform);
|
||||
return downstream.with(builder.toModel());
|
||||
consumer.accept(builder.toModel());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -75,7 +75,7 @@ import static java.lang.classfile.Opcode.LDC_W;
|
|||
|
||||
public final class DirectCodeBuilder
|
||||
extends AbstractDirectBuilder<CodeModel>
|
||||
implements TerminalCodeBuilder, LabelContext {
|
||||
implements TerminalCodeBuilder {
|
||||
private final List<CharacterRange> characterRanges = new ArrayList<>();
|
||||
final List<AbstractPseudoInstruction.ExceptionCatchImpl> handlers = new ArrayList<>();
|
||||
private final List<LocalVariable> localVariables = new ArrayList<>();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -27,7 +27,7 @@ package jdk.internal.classfile.impl;
|
|||
import java.lang.classfile.Label;
|
||||
|
||||
public sealed interface LabelContext
|
||||
permits BufferedCodeBuilder, CodeImpl, DirectCodeBuilder {
|
||||
permits TerminalCodeBuilder, CodeImpl {
|
||||
Label newLabel();
|
||||
Label getLabel(int bci);
|
||||
void setLabelTarget(Label label, int bci);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -26,7 +26,7 @@ package jdk.internal.classfile.impl;
|
|||
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
|
||||
public sealed interface TerminalCodeBuilder extends CodeBuilder
|
||||
permits DirectCodeBuilder, BufferedCodeBuilder, TransformingCodeBuilder {
|
||||
|
||||
public sealed interface TerminalCodeBuilder extends CodeBuilder, LabelContext
|
||||
permits DirectCodeBuilder, BufferedCodeBuilder {
|
||||
int curTopLocal();
|
||||
}
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeModel;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.lang.classfile.CodeElement;
|
||||
import java.lang.classfile.Label;
|
||||
import java.lang.classfile.TypeKind;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
|
||||
public final class TransformingCodeBuilder implements TerminalCodeBuilder {
|
||||
|
||||
final CodeBuilder delegate;
|
||||
final Consumer<CodeElement> consumer;
|
||||
|
||||
public TransformingCodeBuilder(CodeBuilder delegate, Consumer<CodeElement> consumer) {
|
||||
this.delegate = delegate;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBuilder with(CodeElement e) {
|
||||
consumer.accept(e);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CodeModel> original() {
|
||||
return delegate.original();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label newLabel() {
|
||||
return delegate.newLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label startLabel() {
|
||||
return delegate.startLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label endLabel() {
|
||||
return delegate.endLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSlot() {
|
||||
return delegate.receiverSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int parameterSlot(int paramNo) {
|
||||
return delegate.parameterSlot(paramNo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocateLocal(TypeKind typeKind) {
|
||||
return delegate.allocateLocal(typeKind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantPoolBuilder constantPool() {
|
||||
return delegate.constantPool();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue