mirror of
https://github.com/ParkerTenBroeck/coroutines.git
synced 2026-06-06 21:00:35 -04:00
adding semantics to allow for cancelation behavior of local variables
This commit is contained in:
parent
6d05ccc690
commit
3a2c5290f3
4 changed files with 155 additions and 109 deletions
|
|
@ -7,6 +7,10 @@ import future.Future;
|
||||||
import future.Waker;
|
import future.Waker;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
@ -70,7 +74,7 @@ public class AsyncExamples {
|
||||||
|
|
||||||
public static Future<Void, IOException> echo(Socket socket){
|
public static Future<Void, IOException> echo(Socket socket){
|
||||||
try(socket){
|
try(socket){
|
||||||
var buffer = ByteBuffer.allocate(4096*16*3);
|
@Test var buffer = ByteBuffer.allocate(4096*16*3);
|
||||||
while(true){
|
while(true){
|
||||||
var read = socket.read(buffer).await();
|
var read = socket.read(buffer).await();
|
||||||
buffer.clear().limit(read);
|
buffer.clear().limit(read);
|
||||||
|
|
@ -84,7 +88,7 @@ public class AsyncExamples {
|
||||||
|
|
||||||
public static Future<Void, IOException> echoForever(String message){
|
public static Future<Void, IOException> echoForever(String message){
|
||||||
byte[] msg_bytes = message.getBytes(StandardCharsets.UTF_8);
|
byte[] msg_bytes = message.getBytes(StandardCharsets.UTF_8);
|
||||||
try(var socket = Socket.connect(new InetSocketAddress("localhost", 42069)).await()){
|
try(@Test var socket = Socket.connect(new InetSocketAddress("localhost", 42069)).await()){
|
||||||
var buffer = ByteBuffer.allocate(message.length());
|
var buffer = ByteBuffer.allocate(message.length());
|
||||||
while(true){
|
while(true){
|
||||||
buffer.limit(message.length()).put(msg_bytes).position(0);
|
buffer.limit(message.length()).put(msg_bytes).position(0);
|
||||||
|
|
@ -98,8 +102,20 @@ public class AsyncExamples {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return Future.ret(null);
|
return Future.ret(null);
|
||||||
}
|
}
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.TYPE_USE, ElementType.LOCAL_VARIABLE})
|
||||||
|
@interface Test {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Meow implements AutoCloseable{
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
package generators.loadtime;
|
package generators.loadtime;
|
||||||
|
|
||||||
import java.lang.classfile.CodeBuilder;
|
import java.lang.classfile.CodeBuilder;
|
||||||
|
import java.lang.classfile.instruction.LineNumber;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack) {
|
public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack, int bci, LineNumber line) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Frame[label =" + Arrays.toString(locals) + ", s = " + Arrays.toString(stack) + "]";
|
return "Frame[l=" + Arrays.toString(locals) + ", s=" + Arrays.toString(stack) + ", bci=" + bci + ", line="+line + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save_locals(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int loc_off){
|
public void save_locals(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int loc_off){
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package generators.loadtime;
|
package generators.loadtime;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.classfile.*;
|
import java.lang.classfile.*;
|
||||||
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
|
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
|
||||||
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
|
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
|
||||||
|
|
@ -8,6 +9,7 @@ import java.lang.classfile.attribute.StackMapTableAttribute;
|
||||||
import java.lang.classfile.instruction.*;
|
import java.lang.classfile.instruction.*;
|
||||||
import java.lang.constant.*;
|
import java.lang.constant.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
@ -31,6 +33,21 @@ public class FrameTracker {
|
||||||
ITEM_LONG_2ND = 13,
|
ITEM_LONG_2ND = 13,
|
||||||
ITEM_DOUBLE_2ND = 14;
|
ITEM_DOUBLE_2ND = 14;
|
||||||
|
|
||||||
|
public static ArrayList<Frame> frames(StateMachineBuilder smb, CodeModel src_com) {
|
||||||
|
var ft = new FrameTracker(smb, src_com);
|
||||||
|
var frames = new ArrayList<Frame>();
|
||||||
|
for(var coe : src_com){
|
||||||
|
if(coe instanceof Instruction) {
|
||||||
|
frames.add(new Frame(ft.locals(), ft.stack(), ft.bci, ft.current_line_number));
|
||||||
|
System.out.println(frames.getLast() + " " + coe);
|
||||||
|
}
|
||||||
|
ft.encounter(coe);
|
||||||
|
}
|
||||||
|
frames.add(new Frame(ft.locals(), ft.stack(), ft.bci, null));
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
public Type[] locals() {
|
public Type[] locals() {
|
||||||
return locals.toArray(Type[]::new);
|
return locals.toArray(Type[]::new);
|
||||||
}
|
}
|
||||||
|
|
@ -55,21 +72,9 @@ public class FrameTracker {
|
||||||
DOUBLE2_TYPE = simpleType(ITEM_DOUBLE_2ND),
|
DOUBLE2_TYPE = simpleType(ITEM_DOUBLE_2ND),
|
||||||
UNITIALIZED_THIS_TYPE = simpleType(ITEM_UNINITIALIZED_THIS);
|
UNITIALIZED_THIS_TYPE = simpleType(ITEM_UNINITIALIZED_THIS);
|
||||||
|
|
||||||
//frequently used types to reduce footprint
|
static final Type STRING_TYPE = referenceType(CD_String);
|
||||||
static final Type OBJECT_TYPE = referenceType(CD_Object),
|
static final Type METHOD_HANDLE_TYPE = referenceType(CD_MethodHandle);
|
||||||
THROWABLE_TYPE = referenceType(CD_Throwable),
|
static final Type METHOD_TYPE = referenceType(CD_MethodType);
|
||||||
INT_ARRAY_TYPE = referenceType(CD_int.arrayType()),
|
|
||||||
BOOLEAN_ARRAY_TYPE = referenceType(CD_boolean.arrayType()),
|
|
||||||
BYTE_ARRAY_TYPE = referenceType(CD_byte.arrayType()),
|
|
||||||
CHAR_ARRAY_TYPE = referenceType(CD_char.arrayType()),
|
|
||||||
SHORT_ARRAY_TYPE = referenceType(CD_short.arrayType()),
|
|
||||||
LONG_ARRAY_TYPE = referenceType(CD_long.arrayType()),
|
|
||||||
DOUBLE_ARRAY_TYPE = referenceType(CD_double.arrayType()),
|
|
||||||
FLOAT_ARRAY_TYPE = referenceType(CD_float.arrayType()),
|
|
||||||
STRING_TYPE = referenceType(CD_String),
|
|
||||||
CLASS_TYPE = referenceType(CD_Class),
|
|
||||||
METHOD_HANDLE_TYPE = referenceType(CD_MethodHandle),
|
|
||||||
METHOD_TYPE = referenceType(CD_MethodType);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
|
|
@ -101,13 +106,14 @@ public class FrameTracker {
|
||||||
return new Type(ITEM_OBJECT, desc, 0);
|
return new Type(ITEM_OBJECT, desc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type uninitializedType(ClassDesc sym) {
|
static Type uninitializedType(ClassDesc sym, int bci) {
|
||||||
return new Type(ITEM_UNINITIALIZED, sym, 0);
|
return new Type(ITEM_UNINITIALIZED, sym, bci);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override //mandatory override to avoid use of method reference during JDK bootstrap
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return (o instanceof Type t) && t.tag == tag && t.bci == bci && Objects.equals(sym, t.sym);
|
return (o instanceof Type(int tag, ClassDesc sym, int bci))
|
||||||
|
&& tag == this.tag && bci == this.bci && Objects.equals(this.sym, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isCategory2_2nd() {
|
boolean isCategory2_2nd() {
|
||||||
|
|
@ -132,7 +138,7 @@ public class FrameTracker {
|
||||||
case StackMapFrameInfo.ObjectVerificationTypeInfo o -> Type.referenceType(o.classSymbol());
|
case StackMapFrameInfo.ObjectVerificationTypeInfo o -> Type.referenceType(o.classSymbol());
|
||||||
case StackMapFrameInfo.SimpleVerificationTypeInfo s -> Type.simpleType(s.tag());
|
case StackMapFrameInfo.SimpleVerificationTypeInfo s -> Type.simpleType(s.tag());
|
||||||
case StackMapFrameInfo.UninitializedVerificationTypeInfo u -> {
|
case StackMapFrameInfo.UninitializedVerificationTypeInfo u -> {
|
||||||
//Type.simpleType(u.tag());
|
// Type.uninitializedType(null, u.newTarget());
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -153,59 +159,23 @@ public class FrameTracker {
|
||||||
default -> throw new RuntimeException();
|
default -> throw new RuntimeException();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Type toArray() {
|
|
||||||
return switch (tag) {
|
|
||||||
case ITEM_BOOLEAN -> BOOLEAN_ARRAY_TYPE;
|
|
||||||
case ITEM_BYTE -> BYTE_ARRAY_TYPE;
|
|
||||||
case ITEM_CHAR -> CHAR_ARRAY_TYPE;
|
|
||||||
case ITEM_SHORT -> SHORT_ARRAY_TYPE;
|
|
||||||
case ITEM_INTEGER -> INT_ARRAY_TYPE;
|
|
||||||
case ITEM_LONG -> LONG_ARRAY_TYPE;
|
|
||||||
case ITEM_FLOAT -> FLOAT_ARRAY_TYPE;
|
|
||||||
case ITEM_DOUBLE -> DOUBLE_ARRAY_TYPE;
|
|
||||||
case ITEM_OBJECT -> Type.referenceType(sym.arrayType());
|
|
||||||
default -> OBJECT_TYPE;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Type getComponent() {
|
|
||||||
if (isArray()) {
|
|
||||||
var comp = sym.componentType();
|
|
||||||
if (comp.isPrimitive()) {
|
|
||||||
return switch (comp.descriptorString().charAt(0)) {
|
|
||||||
case 'Z' -> Type.BOOLEAN_TYPE;
|
|
||||||
case 'B' -> Type.BYTE_TYPE;
|
|
||||||
case 'C' -> Type.CHAR_TYPE;
|
|
||||||
case 'S' -> Type.SHORT_TYPE;
|
|
||||||
case 'I' -> Type.INTEGER_TYPE;
|
|
||||||
case 'J' -> Type.LONG_TYPE;
|
|
||||||
case 'F' -> Type.FLOAT_TYPE;
|
|
||||||
case 'D' -> Type.DOUBLE_TYPE;
|
|
||||||
default -> Type.TOP_TYPE;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return Type.referenceType(comp);
|
|
||||||
}
|
|
||||||
return Type.TOP_TYPE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final ArrayList<Type> stack = new ArrayList<>();
|
final ArrayList<Type> stack = new ArrayList<>();
|
||||||
final ArrayList<Type> locals = new ArrayList<>();
|
final ArrayList<Type> locals = new ArrayList<>();
|
||||||
|
final StateMachineBuilder smb;
|
||||||
|
|
||||||
|
LineNumber current_line_number = null;
|
||||||
|
int bci = 0;
|
||||||
HashMap<Label, StackMapFrameInfo> stackMapFrames = new HashMap<>();
|
HashMap<Label, StackMapFrameInfo> stackMapFrames = new HashMap<>();
|
||||||
|
|
||||||
final StateMachineBuilder smb;
|
|
||||||
|
|
||||||
|
|
||||||
FrameTracker(StateMachineBuilder smb, CodeModel com) {
|
FrameTracker(StateMachineBuilder smb, CodeModel com) {
|
||||||
this.smb = smb;
|
this.smb = smb;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (var param : smb.params) {
|
for (var param : smb.params) {
|
||||||
if(param == CD_long){
|
if(param == CD_long){
|
||||||
setLocal2(offset, Type.DOUBLE_TYPE, Type.DOUBLE2_TYPE);
|
setLocal2(offset, Type.DOUBLE_TYPE, Type.DOUBLE2_TYPE);
|
||||||
|
|
@ -246,6 +216,11 @@ public class FrameTracker {
|
||||||
: Type.referenceType(desc));
|
: Type.referenceType(desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FrameTracker pushStack(Type... types) {
|
||||||
|
stack.addAll(Arrays.asList(types));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
FrameTracker pushStack(Type type) {
|
FrameTracker pushStack(Type type) {
|
||||||
stack.add(type);
|
stack.add(type);
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -315,10 +290,8 @@ public class FrameTracker {
|
||||||
case String _ -> pushStack(Type.STRING_TYPE);
|
case String _ -> pushStack(Type.STRING_TYPE);
|
||||||
case ClassDesc desc -> pushStack(desc);
|
case ClassDesc desc -> pushStack(desc);
|
||||||
case DynamicConstantDesc dynamicConstantDesc -> pushStack(dynamicConstantDesc.constantType());
|
case DynamicConstantDesc dynamicConstantDesc -> pushStack(dynamicConstantDesc.constantType());
|
||||||
case MethodHandleDesc methodHandleDesc ->
|
case MethodHandleDesc methodHandleDesc -> pushStack(Type.METHOD_HANDLE_TYPE);
|
||||||
throw new RuntimeException();
|
case MethodTypeDesc methodTypeDesc -> pushStack(Type.METHOD_TYPE);
|
||||||
case MethodTypeDesc methodTypeDesc ->
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ConvertInstruction c -> decStack(c.fromType().slotSize()).pushStack(c.toType().upperBound());
|
case ConvertInstruction c -> decStack(c.fromType().slotSize()).pushStack(c.toType().upperBound());
|
||||||
|
|
@ -341,10 +314,27 @@ public class FrameTracker {
|
||||||
decStack(TypeKind.from(param).slotSize());
|
decStack(TypeKind.from(param).slotSize());
|
||||||
pushStack(i.typeSymbol().returnType());
|
pushStack(i.typeSymbol().returnType());
|
||||||
}
|
}
|
||||||
case InvokeInstruction i when i.opcode() == Opcode.INVOKESPECIAL && i.name().equalsString(INIT_NAME) -> {
|
case InvokeInstruction ii when ii.opcode() == Opcode.INVOKESPECIAL && ii.name().equalsString(INIT_NAME) -> {
|
||||||
for(var param : i.typeSymbol().parameterArray())
|
for(var param : ii.typeSymbol().parameterArray())
|
||||||
decStack(TypeKind.from(param).slotSize());
|
decStack(TypeKind.from(param).slotSize());
|
||||||
var ty = popStack();
|
var ty = popStack();
|
||||||
|
if(ty.tag == ITEM_UNINITIALIZED){
|
||||||
|
if(ty.sym!=null&&!ty.sym.equals(ii.owner().asSymbol()))
|
||||||
|
throw new RuntimeException();
|
||||||
|
var init_type = ii.owner().asSymbol();
|
||||||
|
for(int i = 0; i < stack.size(); i ++){
|
||||||
|
if(stack.get(i).bci==ty.bci&&stack.get(i).tag==ITEM_UNINITIALIZED){
|
||||||
|
stack.set(i, Type.referenceType(init_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < locals.size(); i ++){
|
||||||
|
if(locals.get(i).bci==ty.bci&&locals.get(i).tag==ITEM_UNINITIALIZED){
|
||||||
|
locals.set(i, Type.referenceType(init_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case InvokeInstruction i -> {
|
case InvokeInstruction i -> {
|
||||||
for(var param : i.typeSymbol().parameterArray())
|
for(var param : i.typeSymbol().parameterArray())
|
||||||
|
|
@ -359,7 +349,7 @@ public class FrameTracker {
|
||||||
case LookupSwitchInstruction ls -> popStack();
|
case LookupSwitchInstruction ls -> popStack();
|
||||||
case MonitorInstruction m -> popStack();
|
case MonitorInstruction m -> popStack();
|
||||||
case NewMultiArrayInstruction nma -> decStack(nma.dimensions()).pushStack(nma.arrayType().asSymbol());
|
case NewMultiArrayInstruction nma -> decStack(nma.dimensions()).pushStack(nma.arrayType().asSymbol());
|
||||||
case NewObjectInstruction no -> pushStack(no.className().asSymbol());
|
case NewObjectInstruction no -> pushStack(Type.uninitializedType(no.className().asSymbol(), bci));
|
||||||
case NewPrimitiveArrayInstruction npa -> decStack(1).pushStack(npa.typeKind().upperBound().arrayType());
|
case NewPrimitiveArrayInstruction npa -> decStack(1).pushStack(npa.typeKind().upperBound().arrayType());
|
||||||
case NewReferenceArrayInstruction nra -> decStack(1).pushStack(nra.componentType().asSymbol().arrayType());
|
case NewReferenceArrayInstruction nra -> decStack(1).pushStack(nra.componentType().asSymbol().arrayType());
|
||||||
case NopInstruction n -> {}
|
case NopInstruction n -> {}
|
||||||
|
|
@ -388,48 +378,48 @@ public class FrameTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case StackInstruction s -> {
|
case StackInstruction s -> {
|
||||||
Type type1, type2, type3, type4;
|
|
||||||
switch(s.opcode()){
|
switch(s.opcode()){
|
||||||
case POP ->
|
case POP ->
|
||||||
decStack(1);
|
decStack(1);
|
||||||
case POP2 ->
|
case POP2 ->
|
||||||
decStack(2);
|
decStack(2);
|
||||||
case DUP ->
|
case DUP -> {
|
||||||
pushStack(type1 = popStack()).pushStack(type1);
|
var type1 = popStack();
|
||||||
|
pushStack(type1, type1);
|
||||||
|
}
|
||||||
case DUP_X1 -> {
|
case DUP_X1 -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
pushStack(type1).pushStack(type2).pushStack(type1);
|
pushStack(type1, type2, type1);
|
||||||
}
|
}
|
||||||
case DUP_X2 -> {
|
case DUP_X2 -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
type3 = popStack();
|
var type3 = popStack();
|
||||||
pushStack(type1).pushStack(type3).pushStack(type2).pushStack(type1);
|
pushStack(type1, type3, type2, type1);
|
||||||
}
|
}
|
||||||
case DUP2 -> {
|
case DUP2 -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
pushStack(type2).pushStack(type1).pushStack(type2).pushStack(type1);
|
pushStack(type2, type1, type2, type1);
|
||||||
}
|
}
|
||||||
case DUP2_X1 -> {
|
case DUP2_X1 -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
type3 = popStack();
|
var type3 = popStack();
|
||||||
pushStack(type2).pushStack(type1).pushStack(type3).pushStack(type2).pushStack(type1);
|
pushStack(type2, type1, type3, type2, type1);
|
||||||
}
|
}
|
||||||
case DUP2_X2 -> {
|
case DUP2_X2 -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
type3 = popStack();
|
var type3 = popStack();
|
||||||
type4 = popStack();
|
var type4 = popStack();
|
||||||
pushStack(type2).pushStack(type1).pushStack(type4).pushStack(type3).pushStack(type2).pushStack(type1);
|
pushStack(type2, type1, type4, type3, type2, type1);
|
||||||
}
|
}
|
||||||
case SWAP -> {
|
case SWAP -> {
|
||||||
type1 = popStack();
|
var type1 = popStack();
|
||||||
type2 = popStack();
|
var type2 = popStack();
|
||||||
pushStack(type1);
|
pushStack(type1, type2);
|
||||||
pushStack(type2);
|
|
||||||
}
|
}
|
||||||
default -> throw new RuntimeException();
|
default -> throw new RuntimeException();
|
||||||
}
|
}
|
||||||
|
|
@ -448,10 +438,54 @@ public class FrameTracker {
|
||||||
case DiscontinuedInstruction d -> throw new IllegalStateException(d.toString());
|
case DiscontinuedInstruction d -> throw new IllegalStateException(d.toString());
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
bci += ins.sizeInBytes();
|
||||||
|
}
|
||||||
|
case PseudoInstruction p -> {
|
||||||
|
switch(p){
|
||||||
|
case CharacterRange cr -> {
|
||||||
|
}
|
||||||
|
case ExceptionCatch ec -> {
|
||||||
|
}
|
||||||
|
case LabelTarget lt -> {
|
||||||
|
}
|
||||||
|
case LineNumber ln -> current_line_number = ln;
|
||||||
|
case LocalVariable lv -> {
|
||||||
|
}
|
||||||
|
case LocalVariableType lvt -> {
|
||||||
|
}
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case PseudoInstruction _ -> {}
|
|
||||||
case RuntimeInvisibleTypeAnnotationsAttribute _ -> {}
|
case RuntimeInvisibleTypeAnnotationsAttribute _ -> {}
|
||||||
case RuntimeVisibleTypeAnnotationsAttribute _ -> {}
|
case RuntimeVisibleTypeAnnotationsAttribute tas -> {
|
||||||
|
for(var ta : tas.annotations()){
|
||||||
|
switch(ta.targetInfo()){
|
||||||
|
case TypeAnnotation.CatchTarget ct -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.EmptyTarget et -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.FormalParameterTarget fpt -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.LocalVarTarget lvt -> {
|
||||||
|
for(var el : lvt.table()){
|
||||||
|
el.endLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TypeAnnotation.OffsetTarget ot -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.SupertypeTarget stt -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.ThrowsTarget tt -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.TypeArgumentTarget tat -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.TypeParameterBoundTarget tpbt -> {
|
||||||
|
}
|
||||||
|
case TypeAnnotation.TypeParameterTarget tpt -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
case CustomAttribute<?> _ -> {}
|
case CustomAttribute<?> _ -> {}
|
||||||
case StackMapTableAttribute _ -> {}
|
case StackMapTableAttribute _ -> {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public abstract class StateMachineBuilder {
|
||||||
|
|
||||||
ArrayList<LState> lstate = new ArrayList<>();
|
ArrayList<LState> lstate = new ArrayList<>();
|
||||||
|
|
||||||
private final ArrayList<Frame> frames = new ArrayList<>();
|
private final ArrayList<Frame> frames;
|
||||||
|
|
||||||
protected final HashMap<SpecialMethod, SpecialMethodBuilder> smmap = new HashMap<>();
|
protected final HashMap<SpecialMethod, SpecialMethodBuilder> smmap = new HashMap<>();
|
||||||
|
|
||||||
|
|
@ -77,15 +77,7 @@ public abstract class StateMachineBuilder {
|
||||||
this.MTD_init = MethodTypeDesc.of(ConstantDescs.CD_void, params);
|
this.MTD_init = MethodTypeDesc.of(ConstantDescs.CD_void, params);
|
||||||
this.paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum();
|
this.paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum();
|
||||||
|
|
||||||
var lt = new FrameTracker(this, src_com);
|
frames = FrameTracker.frames(this, src_com);
|
||||||
for(var coe : src_com){
|
|
||||||
if(coe instanceof Instruction) {
|
|
||||||
frames.add(new Frame(lt.locals(), lt.stack()));
|
|
||||||
// System.out.println(frames.getLast() + " " + coe);
|
|
||||||
}
|
|
||||||
lt.encounter(coe);
|
|
||||||
}
|
|
||||||
frames.add(new Frame(lt.locals(), lt.stack()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public record WithFrame(CodeElement coe, Frame frame){}
|
public record WithFrame(CodeElement coe, Frame frame){}
|
||||||
|
|
@ -236,7 +228,10 @@ public abstract class StateMachineBuilder {
|
||||||
for (var wf : with_frames()) {
|
for (var wf : with_frames()) {
|
||||||
if (wf.coe() instanceof InvokeInstruction is) {
|
if (wf.coe() instanceof InvokeInstruction is) {
|
||||||
var h = smmap.get(new SpecialMethod(is.owner().asSymbol(), is.name().stringValue(), is.typeSymbol()));
|
var h = smmap.get(new SpecialMethod(is.owner().asSymbol(), is.name().stringValue(), is.typeSymbol()));
|
||||||
if(h!=null) handlers.get(i++).build_prelude(this, cob, wf.frame());
|
if(h!=null) {
|
||||||
|
if(wf.frame.line()!=null)cob.with(wf.frame.line());
|
||||||
|
handlers.get(i++).build_prelude(this, cob, wf.frame());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue