mirror of
https://github.com/ParkerTenBroeck/coroutines.git
synced 2026-06-06 21:00:35 -04:00
made class behave like a static inner class, write all modified classes to directory
This commit is contained in:
parent
c3cb7cb884
commit
3cac1da371
5 changed files with 87 additions and 61 deletions
|
|
@ -8,8 +8,8 @@ public class Main implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
await();
|
// await();
|
||||||
// lexer();
|
lexer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void await(){
|
void await(){
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,13 @@ package generator.runtime;
|
||||||
import generator.Gen;
|
import generator.Gen;
|
||||||
|
|
||||||
import java.lang.classfile.*;
|
import java.lang.classfile.*;
|
||||||
|
import java.lang.classfile.attribute.InnerClassInfo;
|
||||||
|
import java.lang.classfile.attribute.InnerClassesAttribute;
|
||||||
|
import java.lang.classfile.attribute.NestHostAttribute;
|
||||||
import java.lang.constant.ClassDesc;
|
import java.lang.constant.ClassDesc;
|
||||||
import java.lang.constant.ConstantDescs;
|
import java.lang.constant.ConstantDescs;
|
||||||
import java.lang.constant.MethodTypeDesc;
|
import java.lang.constant.MethodTypeDesc;
|
||||||
|
import java.lang.reflect.AccessFlag;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class GeneratorBuilder {
|
public class GeneratorBuilder {
|
||||||
|
|
@ -23,19 +27,19 @@ public class GeneratorBuilder {
|
||||||
public final static MethodTypeDesc MTD_Gen = MethodTypeDesc.of(CD_Gen);
|
public final static MethodTypeDesc MTD_Gen = MethodTypeDesc.of(CD_Gen);
|
||||||
public static MethodTypeDesc MTD_Obj = MethodTypeDesc.of(ConstantDescs.CD_Object);
|
public static MethodTypeDesc MTD_Obj = MethodTypeDesc.of(ConstantDescs.CD_Object);
|
||||||
|
|
||||||
public final String name;
|
public final ClassDesc CD_this;
|
||||||
public final ClassDesc CD_this_gen;
|
|
||||||
public final ClassDesc[] params;
|
public final ClassDesc[] params;
|
||||||
public final MethodTypeDesc MTD_init;
|
public final MethodTypeDesc MTD_init;
|
||||||
public final int paramSlotOff;
|
public final int paramSlotOff;
|
||||||
|
public final ClassModel clm;
|
||||||
|
|
||||||
public interface ParamConsumer{
|
public interface ParamConsumer{
|
||||||
void consume(String param, int slot, ClassDesc type);
|
void consume(String param, int slot, ClassDesc type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneratorBuilder(String name, ClassDesc[] params){
|
public GeneratorBuilder(ClassModel clm, ClassDesc cd, ClassDesc[] params){
|
||||||
this.name = name;
|
this.clm = clm;
|
||||||
CD_this_gen = ClassDesc.of(name);
|
CD_this = cd;
|
||||||
this.params = params;
|
this.params = params;
|
||||||
MTD_init = MethodTypeDesc.of(ConstantDescs.CD_void, params);
|
MTD_init = MethodTypeDesc.of(ConstantDescs.CD_void, params);
|
||||||
paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum();
|
paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum();
|
||||||
|
|
@ -50,15 +54,20 @@ public class GeneratorBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildGeneratorMethodShim(CodeBuilder cob){
|
public void buildGeneratorMethodShim(CodeBuilder cob){
|
||||||
cob.new_(CD_this_gen).dup();
|
cob.new_(CD_this).dup();
|
||||||
params(0, (_, slot, type) -> {
|
params(0, (_, slot, type) -> {
|
||||||
cob.loadLocal(TypeKind.from(type), slot);
|
cob.loadLocal(TypeKind.from(type), slot);
|
||||||
});
|
});
|
||||||
cob.invokespecial(CD_this_gen, ConstantDescs.INIT_NAME, MTD_init).areturn();
|
cob.invokespecial(CD_this, ConstantDescs.INIT_NAME, MTD_init).areturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] buildGenerator(CodeModel com){
|
public byte[] buildGenerator(CodeModel com){
|
||||||
return ClassFile.of(ClassFile.StackMapsOption.STACK_MAPS_WHEN_REQUIRED, ClassFile.DebugElementsOption.PASS_DEBUG, ClassFile.LineNumbersOption.PASS_LINE_NUMBERS, ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(CD_this_gen, clb -> {
|
return ClassFile.of(ClassFile.StackMapsOption.STACK_MAPS_WHEN_REQUIRED, ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(CD_this, clb -> {
|
||||||
|
|
||||||
|
clm.findAttributes(Attributes.sourceFile()).forEach(clb::with);
|
||||||
|
clb.with(InnerClassesAttribute.of(InnerClassInfo.of(CD_this, Optional.of(clm.thisClass().asSymbol()), Optional.of(CD_this.displayName().split("\\$")[1]), AccessFlag.PUBLIC, AccessFlag.FINAL, AccessFlag.STATIC)));
|
||||||
|
clb.with(NestHostAttribute.of(clm.thisClass()));
|
||||||
|
|
||||||
clb.withInterfaces(List.of(clb.constantPool().classEntry(CD_Gen)));
|
clb.withInterfaces(List.of(clb.constantPool().classEntry(CD_Gen)));
|
||||||
// parameter fields
|
// parameter fields
|
||||||
params(0, (param, _, type) -> {
|
params(0, (param, _, type) -> {
|
||||||
|
|
@ -71,7 +80,7 @@ public class GeneratorBuilder {
|
||||||
clb.withMethod(ConstantDescs.INIT_NAME, MTD_init, ClassFile.ACC_PUBLIC, mb -> mb.withCode(cob -> {
|
clb.withMethod(ConstantDescs.INIT_NAME, MTD_init, ClassFile.ACC_PUBLIC, mb -> mb.withCode(cob -> {
|
||||||
cob.aload(0).invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void);
|
cob.aload(0).invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void);
|
||||||
params(1, (param, slot, type) -> {
|
params(1, (param, slot, type) -> {
|
||||||
cob.aload(0).loadLocal(TypeKind.from(type), slot).putfield(CD_this_gen, param, type);
|
cob.aload(0).loadLocal(TypeKind.from(type), slot).putfield(CD_this, param, type);
|
||||||
});
|
});
|
||||||
cob.return_();
|
cob.return_();
|
||||||
}));
|
}));
|
||||||
|
|
@ -88,7 +97,7 @@ public class GeneratorBuilder {
|
||||||
tcob -> new StateMachineBuilder(this, clb, tcob, com).generateStateMachine(),
|
tcob -> new StateMachineBuilder(this, clb, tcob, com).generateStateMachine(),
|
||||||
// catch anything set our state to -1 and throw the exception
|
// catch anything set our state to -1 and throw the exception
|
||||||
ctb -> ctb.catchingAll(
|
ctb -> ctb.catchingAll(
|
||||||
blc -> blc.aload(0).loadConstant(-1).putfield(CD_this_gen, STATE_NAME, ConstantDescs.CD_int).athrow()
|
blc -> blc.aload(0).loadConstant(-1).putfield(CD_this, STATE_NAME, ConstantDescs.CD_int).athrow()
|
||||||
)
|
)
|
||||||
).aconst_null().areturn();
|
).aconst_null().areturn();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,16 @@ import generator.Fun;
|
||||||
import generator.Gen;
|
import generator.Gen;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.classfile.*;
|
import java.lang.classfile.*;
|
||||||
import java.lang.classfile.attribute.StackMapFrameInfo;
|
import java.lang.classfile.attribute.*;
|
||||||
import java.lang.classfile.instruction.*;
|
import java.lang.classfile.constantpool.ClassEntry;
|
||||||
import java.lang.constant.ClassDesc;
|
import java.lang.constant.ClassDesc;
|
||||||
import java.lang.constant.ConstantDescs;
|
import java.lang.constant.ConstantDescs;
|
||||||
import java.lang.constant.MethodTypeDesc;
|
|
||||||
import java.lang.reflect.AccessFlag;
|
import java.lang.reflect.AccessFlag;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static java.lang.classfile.attribute.StackMapFrameInfo.SimpleVerificationTypeInfo.TOP;
|
|
||||||
|
|
||||||
public class GeneratorClassLoader extends ClassLoader {
|
public class GeneratorClassLoader extends ClassLoader {
|
||||||
private final HashMap<String, byte[]> customClazzDefMap = new HashMap<>();
|
private final HashMap<String, byte[]> customClazzDefMap = new HashMap<>();
|
||||||
|
|
@ -29,12 +23,19 @@ public class GeneratorClassLoader extends ClassLoader {
|
||||||
super(parent);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add(String name, byte[] def){
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Path.of("out/modified/generators/" + name.replace(".", "/")).getParent());
|
||||||
|
Files.write(Path.of("out/modified/generators/" + name.replace(".", "/") + ".class"), def);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
customClazzDefMap.put(name, def);
|
||||||
|
customClazzMap.put(name, defineClass(name, def, 0, def.length));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||||
// if(customClazzDefMap.containsKey(name))
|
|
||||||
// return super.loadClass(name);
|
|
||||||
if (customClazzDefMap.get(name) instanceof byte[] bytes)
|
|
||||||
customClazzMap.put(name, defineClass(name, bytes, 0, bytes.length));
|
|
||||||
if (customClazzMap.get(name) instanceof Class<?> clazz)
|
if (customClazzMap.get(name) instanceof Class<?> clazz)
|
||||||
return clazz;
|
return clazz;
|
||||||
if (name.startsWith("java"))
|
if (name.startsWith("java"))
|
||||||
|
|
@ -43,9 +44,7 @@ public class GeneratorClassLoader extends ClassLoader {
|
||||||
var p = "/" + name.replace('.', '/') + ".class";
|
var p = "/" + name.replace('.', '/') + ".class";
|
||||||
try (var stream = Fun.class.getResourceAsStream(p)) {
|
try (var stream = Fun.class.getResourceAsStream(p)) {
|
||||||
var bytes = Objects.requireNonNull(stream).readAllBytes();
|
var bytes = Objects.requireNonNull(stream).readAllBytes();
|
||||||
bytes = searchForGenerators(bytes);
|
add(name, searchForGenerators(bytes));
|
||||||
customClazzDefMap.put(name, bytes);
|
|
||||||
customClazzMap.put(name, defineClass(name, bytes, 0, bytes.length));
|
|
||||||
return customClazzMap.get(name);
|
return customClazzMap.get(name);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ClassNotFoundException(name, e);
|
throw new ClassNotFoundException(name, e);
|
||||||
|
|
@ -53,24 +52,44 @@ public class GeneratorClassLoader extends ClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] searchForGenerators(byte[] in) {
|
public byte[] searchForGenerators(byte[] in) {
|
||||||
var clm = ClassFile.of(ClassFile.DebugElementsOption.PASS_DEBUG, ClassFile.LineNumbersOption.PASS_LINE_NUMBERS, ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).parse(in);
|
var clm = ClassFile.of(ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).parse(in);
|
||||||
var isGen = clm.thisClass().asSymbol().descriptorString().equals(Gen.class.descriptorString());
|
var isGen = clm.thisClass().asSymbol().descriptorString().equals(Gen.class.descriptorString());
|
||||||
return ClassFile.of(ClassFile.DebugElementsOption.PASS_DEBUG, ClassFile.LineNumbersOption.PASS_LINE_NUMBERS, ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(clm.thisClass().asSymbol(), cb -> {
|
|
||||||
|
|
||||||
|
var nestMem = new ArrayList<ClassDesc>();
|
||||||
|
var innerCl = new ArrayList<InnerClassInfo>();
|
||||||
|
clm.findAttributes(Attributes.nestMembers()).forEach(i -> nestMem.addAll(i.nestMembers().stream().map(ClassEntry::asSymbol).toList()));
|
||||||
|
clm.findAttributes(Attributes.innerClasses()).forEach(i -> innerCl.addAll(i.classes()));
|
||||||
|
|
||||||
|
return ClassFile.of(ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(clm.thisClass().asSymbol(), cb -> {
|
||||||
for (var ce : clm) {
|
for (var ce : clm) {
|
||||||
if (ce instanceof MethodModel mem && !isGen) {
|
if (ce instanceof MethodModel mem && !isGen) {
|
||||||
var methodRetGen = mem.methodTypeSymbol().returnType().descriptorString().equals(Gen.class.descriptorString());
|
var methodRetGen = mem.methodTypeSymbol().returnType().descriptorString().equals(Gen.class.descriptorString());
|
||||||
if (!methodRetGen) {
|
if (!methodRetGen) {
|
||||||
cb.with(mem);
|
cb.with(mem);
|
||||||
} else{
|
} else{
|
||||||
generatorMethod(cb, mem, clm);
|
var gcd = generatorMethod(cb, mem, clm);
|
||||||
|
innerCl.add(InnerClassInfo.of(gcd, Optional.of(clm.thisClass().asSymbol()), Optional.of(gcd.displayName()), AccessFlag.PUBLIC, AccessFlag.FINAL, AccessFlag.STATIC));
|
||||||
|
// nestMem.add(ClassDesc.of(gcd.displayName()));
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
cb.with(ce);
|
else if (ce instanceof Attribute<?> e){
|
||||||
|
if (e.attributeMapper() != Attributes.nestMembers() && e.attributeMapper() != Attributes.innerClasses())
|
||||||
|
cb.with(ce);
|
||||||
|
}
|
||||||
|
else cb.with(ce);
|
||||||
}
|
}
|
||||||
|
if(!innerCl.isEmpty())
|
||||||
|
cb.with(InnerClassesAttribute.of(innerCl));
|
||||||
|
if(!nestMem.isEmpty())
|
||||||
|
cb.with(NestMembersAttribute.ofSymbols(nestMem));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generatorMethod(ClassBuilder cb, MethodModel mem, ClassModel clm) {
|
private ClassDesc generatorMethod(ClassBuilder cb, MethodModel mem, ClassModel clm) {
|
||||||
|
|
||||||
|
AtomicReference<ClassDesc> gcd = new AtomicReference<>();
|
||||||
|
|
||||||
cb.withMethod(mem.methodName(), mem.methodType(), mem.flags().flagsMask(), mb -> {
|
cb.withMethod(mem.methodName(), mem.methodType(), mem.flags().flagsMask(), mb -> {
|
||||||
for (var me : mem) {
|
for (var me : mem) {
|
||||||
if (me instanceof CodeModel com) {
|
if (me instanceof CodeModel com) {
|
||||||
|
|
@ -79,21 +98,17 @@ public class GeneratorClassLoader extends ClassLoader {
|
||||||
if (!mem.flags().has(AccessFlag.STATIC)) {
|
if (!mem.flags().has(AccessFlag.STATIC)) {
|
||||||
mts = mts.insertParameterTypes(0, clm.thisClass().asSymbol());
|
mts = mts.insertParameterTypes(0, clm.thisClass().asSymbol());
|
||||||
}
|
}
|
||||||
var name = "Gen_" + clm.thisClass().name().stringValue() + "_" + mem.methodName().stringValue() + "_" + customClazzDefMap.size();
|
var name = clm.thisClass().name().stringValue()+"$Gen_" + mem.methodName().stringValue() + "_" + customClazzDefMap.size();
|
||||||
var gb = new GeneratorBuilder(name, mts.parameterArray());
|
|
||||||
|
gcd.set(ClassDesc.of(clm.thisClass().asSymbol().packageName(), name));
|
||||||
|
var gb = new GeneratorBuilder(clm, gcd.get(), mts.parameterArray());
|
||||||
|
|
||||||
mb.withCode(gb::buildGeneratorMethodShim);
|
mb.withCode(gb::buildGeneratorMethodShim);
|
||||||
addGenerator(gb.CD_this_gen.displayName(), gb.buildGenerator(com));
|
add(gb.CD_this.displayName(), gb.buildGenerator(com));
|
||||||
} else mb.with(me);
|
} else mb.with(me);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
protected void addGenerator(String name, byte[] def){
|
return gcd.get();
|
||||||
try {
|
|
||||||
Files.write(Path.of("out/production/generators/" + name + ".class"), def);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
customClazzDefMap.put(name, def);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class LocalTracker {
|
||||||
for (var smfi : attr.entries()) {
|
for (var smfi : attr.entries()) {
|
||||||
var locals = new ArrayList<>(smfi.locals());
|
var locals = new ArrayList<>(smfi.locals());
|
||||||
for (int i = 0; i < smb.gb.params.length; i++) locals.removeFirst();
|
for (int i = 0; i < smb.gb.params.length; i++) locals.removeFirst();
|
||||||
locals.addFirst(StackMapFrameInfo.ObjectVerificationTypeInfo.of(smb.gb.CD_this_gen));
|
locals.addFirst(StackMapFrameInfo.ObjectVerificationTypeInfo.of(smb.gb.CD_this));
|
||||||
entries.add(StackMapFrameInfo.of(smfi.target(), locals, smfi.stack()));
|
entries.add(StackMapFrameInfo.of(smfi.target(), locals, smfi.stack()));
|
||||||
stackMapFrames.put(smfi.target(), entries.getLast());
|
stackMapFrames.put(smfi.target(), entries.getLast());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ public class StateMachineBuilder {
|
||||||
public void handle(StateMachineBuilder smb) {
|
public void handle(StateMachineBuilder smb) {
|
||||||
if(is_void)smb.cob.aconst_null();
|
if(is_void)smb.cob.aconst_null();
|
||||||
|
|
||||||
smb.lt.savingLocals(smb.gb.CD_this_gen, smb.cob, () -> {
|
smb.lt.savingLocals(smb.gb.CD_this, smb.cob, () -> {
|
||||||
smb.cob.aload(0).loadConstant(resume_state).putfield(smb.gb.CD_this_gen, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound())
|
smb.cob.aload(0).loadConstant(resume_state).putfield(smb.gb.CD_this, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound())
|
||||||
.new_(GeneratorBuilder.CD_Yield)
|
.new_(GeneratorBuilder.CD_Yield)
|
||||||
.dup_x1()
|
.dup_x1()
|
||||||
.swap()
|
.swap()
|
||||||
|
|
@ -76,7 +76,7 @@ public class StateMachineBuilder {
|
||||||
public void handle(StateMachineBuilder smb) {
|
public void handle(StateMachineBuilder smb) {
|
||||||
if(is_void)smb.cob.aconst_null();
|
if(is_void)smb.cob.aconst_null();
|
||||||
|
|
||||||
smb.cob.aload(0).loadConstant(-1).putfield(smb.gb.CD_this_gen, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound())
|
smb.cob.aload(0).loadConstant(-1).putfield(smb.gb.CD_this, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound())
|
||||||
.new_(GeneratorBuilder.CD_Ret)
|
.new_(GeneratorBuilder.CD_Ret)
|
||||||
.dup_x1()
|
.dup_x1()
|
||||||
.swap()
|
.swap()
|
||||||
|
|
@ -97,7 +97,7 @@ public class StateMachineBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(StateMachineBuilder smb) {
|
public void handle(StateMachineBuilder smb) {
|
||||||
smb.cob.aload(0).loadConstant(yield_state).putfield(smb.gb.CD_this_gen, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound());
|
smb.cob.aload(0).loadConstant(yield_state).putfield(smb.gb.CD_this, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound());
|
||||||
var start = smb.cob.newBoundLabel();
|
var start = smb.cob.newBoundLabel();
|
||||||
smb.cob.dup().dup()
|
smb.cob.dup().dup()
|
||||||
.invokeinterface(GeneratorBuilder.CD_Gen, "next", MethodTypeDesc.of(GeneratorBuilder.CD_Res)).dup()
|
.invokeinterface(GeneratorBuilder.CD_Gen, "next", MethodTypeDesc.of(GeneratorBuilder.CD_Res)).dup()
|
||||||
|
|
@ -105,10 +105,10 @@ public class StateMachineBuilder {
|
||||||
smb.cob.ifThenElse(bcb -> {
|
smb.cob.ifThenElse(bcb -> {
|
||||||
bcb.checkcast(GeneratorBuilder.CD_Ret).invokevirtual(GeneratorBuilder.CD_Ret, "v", MethodTypeDesc.of(ConstantDescs.CD_Object)).swap().pop();
|
bcb.checkcast(GeneratorBuilder.CD_Ret).invokevirtual(GeneratorBuilder.CD_Ret, "v", MethodTypeDesc.of(ConstantDescs.CD_Object)).swap().pop();
|
||||||
}, bcb -> {
|
}, bcb -> {
|
||||||
smb.lt.savingLocals(smb.gb.CD_this_gen, bcb, () -> {
|
smb.lt.savingLocals(smb.gb.CD_this, bcb, () -> {
|
||||||
bcb.swap().loadLocal(TypeKind.from(smb.gb.CD_this_gen), 0).swap().putfield(smb.gb.CD_this_gen, "meow", GeneratorBuilder.CD_Gen);
|
bcb.swap().loadLocal(TypeKind.from(smb.gb.CD_this), 0).swap().putfield(smb.gb.CD_this, "meow", GeneratorBuilder.CD_Gen);
|
||||||
bcb.areturn().labelBinding(yield_label);
|
bcb.areturn().labelBinding(yield_label);
|
||||||
bcb.loadLocal(TypeKind.from(smb.gb.CD_this_gen), 0).getfield(smb.gb.CD_this_gen, "meow", GeneratorBuilder.CD_Gen);
|
bcb.loadLocal(TypeKind.from(smb.gb.CD_this), 0).getfield(smb.gb.CD_this, "meow", GeneratorBuilder.CD_Gen);
|
||||||
});
|
});
|
||||||
bcb.goto_(start);
|
bcb.goto_(start);
|
||||||
});
|
});
|
||||||
|
|
@ -148,10 +148,10 @@ public class StateMachineBuilder {
|
||||||
handlers.add(handler.apply(this));
|
handlers.add(handler.apply(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cob.aload(0).getfield(gb.CD_this_gen, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound()).lookupswitch(invalidState, stateSwitchCases);
|
cob.aload(0).getfield(gb.CD_this, GeneratorBuilder.STATE_NAME, TypeKind.INT.upperBound()).lookupswitch(invalidState, stateSwitchCases);
|
||||||
var start = cob.startLabel();
|
var start = cob.startLabel();
|
||||||
var end = cob.newLabel();
|
var end = cob.newLabel();
|
||||||
cob.localVariable(0, "this", gb.CD_this_gen, start, end);
|
cob.localVariable(0, "this", gb.CD_this, start, end);
|
||||||
|
|
||||||
SpecialMethodHandler currentHandler = null;
|
SpecialMethodHandler currentHandler = null;
|
||||||
|
|
||||||
|
|
@ -189,6 +189,8 @@ public class StateMachineBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System.out.println(coe);
|
||||||
|
|
||||||
switch (coe) {
|
switch (coe) {
|
||||||
// locals which were once function parameters can be ignored
|
// locals which were once function parameters can be ignored
|
||||||
case LocalVariable lv when lv.slot() < gb.paramSlotOff -> {
|
case LocalVariable lv when lv.slot() < gb.paramSlotOff -> {
|
||||||
|
|
@ -198,21 +200,21 @@ public class StateMachineBuilder {
|
||||||
|
|
||||||
// increment indexes into the stack
|
// increment indexes into the stack
|
||||||
case IncrementInstruction ii when ii.slot() < gb.paramSlotOff ->
|
case IncrementInstruction ii when ii.slot() < gb.paramSlotOff ->
|
||||||
cob.aload(0).dup().getfield(gb.CD_this_gen, GeneratorBuilder.PARAM_PREFIX + ii.slot(), ConstantDescs.CD_int)
|
cob.aload(0).dup().getfield(gb.CD_this, GeneratorBuilder.PARAM_PREFIX + ii.slot(), ConstantDescs.CD_int)
|
||||||
.loadConstant(ii.constant()).iadd()
|
.loadConstant(ii.constant()).iadd()
|
||||||
.putfield(gb.CD_this_gen, GeneratorBuilder.PARAM_PREFIX + ii.slot(), ConstantDescs.CD_int);
|
.putfield(gb.CD_this, GeneratorBuilder.PARAM_PREFIX + ii.slot(), ConstantDescs.CD_int);
|
||||||
case IncrementInstruction ii -> cob.iinc(ii.slot() - gb.paramSlotOff + 1, ii.constant());
|
case IncrementInstruction ii -> cob.iinc(ii.slot() - gb.paramSlotOff + 1, ii.constant());
|
||||||
|
|
||||||
// convert local function parameters to class fields and offset regular locals
|
// convert local function parameters to class fields and offset regular locals
|
||||||
case LoadInstruction li when li.slot() < gb.paramSlotOff ->
|
case LoadInstruction li when li.slot() < gb.paramSlotOff ->
|
||||||
cob.aload(0).getfield(gb.CD_this_gen, GeneratorBuilder.PARAM_PREFIX + li.slot(), lt.paramType(li.slot()));
|
cob.aload(0).getfield(gb.CD_this, GeneratorBuilder.PARAM_PREFIX + li.slot(), lt.paramType(li.slot()));
|
||||||
case LoadInstruction li -> cob.loadLocal(li.typeKind(), li.slot() - gb.paramSlotOff + 1);
|
case LoadInstruction li -> cob.loadLocal(li.typeKind(), li.slot() - gb.paramSlotOff + 1);
|
||||||
|
|
||||||
// convert local function parameters to class fields and offset regular locals
|
// convert local function parameters to class fields and offset regular locals
|
||||||
case StoreInstruction ls when ls.slot() < gb.paramSlotOff && ls.typeKind().slotSize() == 2 ->
|
case StoreInstruction ls when ls.slot() < gb.paramSlotOff && ls.typeKind().slotSize() == 2 ->
|
||||||
cob.aload(0).dup_x2().pop().putfield(gb.CD_this_gen, GeneratorBuilder.PARAM_PREFIX + ls.slot(), lt.paramType(ls.slot()));
|
cob.aload(0).dup_x2().pop().putfield(gb.CD_this, GeneratorBuilder.PARAM_PREFIX + ls.slot(), lt.paramType(ls.slot()));
|
||||||
case StoreInstruction ls when ls.slot() < gb.paramSlotOff ->
|
case StoreInstruction ls when ls.slot() < gb.paramSlotOff ->
|
||||||
cob.aload(0).swap().putfield(gb.CD_this_gen, GeneratorBuilder.PARAM_PREFIX + ls.slot(), lt.paramType(ls.slot()));
|
cob.aload(0).swap().putfield(gb.CD_this, GeneratorBuilder.PARAM_PREFIX + ls.slot(), lt.paramType(ls.slot()));
|
||||||
case StoreInstruction ls -> {
|
case StoreInstruction ls -> {
|
||||||
lt.trackLocal(ls.slot() - gb.paramSlotOff + 1, ls.typeKind());
|
lt.trackLocal(ls.slot() - gb.paramSlotOff + 1, ls.typeKind());
|
||||||
cob.storeLocal(ls.typeKind(), ls.slot() - gb.paramSlotOff + 1);
|
cob.storeLocal(ls.typeKind(), ls.slot() - gb.paramSlotOff + 1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue