so many small issues all at once

This commit is contained in:
Parker TenBroeck 2025-04-28 23:36:07 -04:00
parent 21412f4670
commit b0d6737b07
8 changed files with 167 additions and 57 deletions

View file

@ -1,8 +1,6 @@
import async_example.Delay;
import async_example.Jokio;
import generator.future.Future;
import generator.future.Waker;
import java.util.Timer;
import java.util.TimerTask;
public class Examples {
// public static Gen<String, Void> parse(String str){
@ -69,49 +67,24 @@ public class Examples {
// return Gen.ret();
// }
public static class Delay implements Future<String>{
private final static Timer timer;
static{
timer = new Timer(true);
}
private int delay;
private boolean ready;
public Delay(int ms){
if(ms<0)throw new IllegalArgumentException("Delay cannot be negative");
delay = ms;
}
@Override
public synchronized Object poll(Waker waker) {
if(delay==0){
ready=true;
delay=-1;
return null;
}
if(delay != -1){
timer.schedule(new TimerTask() {
@Override
public void run() {
ready = true;
waker.wake();
}
}, delay);
delay = -1;
}
if(ready)return null;
return Pending.INSTANCE;
}
}
public static Future<String> awaitTest2(int number){
((Future<?>)new Delay(number)).await();
return Future.ret(number+"ms");
}
public Future<String> awaitTest(int number){
var result = awaitTest2(number).await();
var rt = Jokio.runtime().await();
rt.spawn(awaitTest2(5000));
// closing(100);
// closing(10).await();
return Future.ret("Result: " + result);
}
public Future<String> closing(int number){
try(var m = new Meow()){
var result = awaitTest2(number).await();
return Future.ret("Result: " + result);
return Future.ret(result);
}
}

View file

@ -1,10 +1,9 @@
import async_example.Jokio;
import generator.RT;
import generator.future.Future;
import generator.future.Waker;
import generator.gen.Gen;
import java.util.function.Supplier;
public class Main implements Runnable {
public static void main(String[] args) {
RT.runWithGeneratorSupport(Main.class);
@ -58,7 +57,7 @@ public class Main implements Runnable {
}
void await(){
System.out.println(simple_async_rt(new Examples().awaitTest(2000)));
new Jokio().blocking(new Examples().awaitTest(2000));
}

View file

@ -0,0 +1,52 @@
package async_example;
import generator.future.Future;
import generator.future.Waker;
import java.util.Timer;
import java.util.TimerTask;
public class Delay implements Future<String> {
private final static Timer timer;
private TimerTask task;
static {
timer = new Timer(true);
}
private int delay;
private boolean ready;
public Delay(int ms) {
if (ms < 0) throw new IllegalArgumentException("async_example.Delay cannot be negative");
delay = ms;
}
@Override
public void cancel() {
if (task != null) task.cancel();
}
@Override
public synchronized Object poll(Waker waker) {
if (delay == 0) {
ready = true;
delay = -1;
return null;
}
if (delay != -1) {
task = new TimerTask() {
@Override
public void run() {
ready = true;
waker.wake();
}
};
timer.schedule(task, delay);
delay = -1;
}
if (ready) return null;
return Pending.INSTANCE;
}
}

View file

@ -0,0 +1,73 @@
package async_example;
import generator.future.Future;
import generator.future.Waker;
import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
public class Jokio implements Runnable{
private class Task<T> implements Waker{
public final Future<T> future;
private Task(Future<T> future) {
this.future = future;
}
@Override
public void wake() {
synchronized (Jokio.this){
woke.add(this);
Jokio.this.notifyAll();
}
}
public Jokio runtime(){
return Jokio.this;
}
}
public static Future<Jokio> runtime(){
return new Future<>() {
@Override
public Jokio poll(Waker waker) {
return ((Task<?>)waker).runtime();
}
};
}
private final HashSet<Task<?>> current = new HashSet<>();
private final Queue<Task<?>> woke = new ArrayDeque<>();
public void blocking(Future<?> fut){
spawn(fut).run();
}
public synchronized Jokio spawn(Future<?> future){
var task = new Task<>(future);
current.add(task);
woke.add(task);
return this;
}
@Override
public synchronized void run(){
while(!current.isEmpty()) {
while(woke.isEmpty()) {
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
var task = woke.poll();
var result = task.future.poll(task);
if(result!=Future.Pending.INSTANCE) {
current.remove(task);
System.out.println(result);
}
}
}
}

View file

@ -60,7 +60,7 @@ public class GeneratorClassLoader extends ClassLoader {
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 -> {
return ClassFile.of(ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES, ClassFile.StackMapsOption.STACK_MAPS_WHEN_REQUIRED).build(clm.thisClass().asSymbol(), cb -> {
for (var ce : clm) {
if (ce instanceof MethodModel mem && !isGen && !isFuture) {
StateMachineBuilder builder = null;
@ -104,6 +104,10 @@ public class GeneratorClassLoader extends ClassLoader {
var smb = new FutureSMBuilder(src_clm, src_mem, com);
try{
add(smb.CD_this.displayName(), smb.buildStateMachine());
cb.withMethod(src_mem.methodName(), src_mem.methodType(), src_mem.flags().flagsMask(), mb -> {
mb.withCode(smb::buildSourceMethodShim);
});
}catch (Exception e){
e.printStackTrace();
cb.withMethod(src_mem.methodName(), src_mem.methodType(), src_mem.flags().flagsMask(), mb -> {
@ -111,9 +115,6 @@ public class GeneratorClassLoader extends ClassLoader {
});
return smb;
}
cb.withMethod(src_mem.methodName(), src_mem.methodType(), src_mem.flags().flagsMask(), mb -> {
mb.withCode(smb::buildSourceMethodShim);
});
return smb;
}
}

View file

@ -146,6 +146,7 @@ public class LocalTracker {
case ITEM_FLOAT -> CD_float;
case ITEM_DOUBLE -> CD_double;
case ITEM_OBJECT -> sym;
case ITEM_NULL -> CD_Object;
default -> throw new RuntimeException();
};
}
@ -433,7 +434,7 @@ public class LocalTracker {
case TableSwitchInstruction ts -> popStack();
case ThrowInstruction t -> popStack();
case TypeCheckInstruction tc -> {}
case TypeCheckInstruction tc -> decStack(1).pushStack(tc.type().asSymbol());
case DiscontinuedInstruction d -> throw new IllegalStateException(d.toString());
default -> throw new IllegalStateException();
}

View file

@ -58,7 +58,7 @@ public abstract class StateMachineBuilder {
if (!src_mem.flags().has(AccessFlag.STATIC)) {
mts = mts.insertParameterTypes(0, src_clm.thisClass().asSymbol());
}
var name = src_clm.thisClass().name().stringValue() + "$" + src_mem.methodName().stringValue() + "$" + uniqueName();
var name = src_clm.thisClass().asSymbol().displayName() + "$" + src_mem.methodName().stringValue() + "$" + uniqueName();
this.CD_this = ClassDesc.of(src_clm.thisClass().asSymbol().packageName(), name);
this.params = mts.parameterArray();
@ -84,7 +84,7 @@ public abstract class StateMachineBuilder {
}
public byte[] buildStateMachine(){
return ClassFile.of(ClassFile.StackMapsOption.STACK_MAPS_WHEN_REQUIRED, ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(CD_this, clb -> {
return ClassFile.of(ClassFile.AttributesProcessingOption.PASS_ALL_ATTRIBUTES).build(CD_this, clb -> {
if(shouldBeInnerClass()){
src_clm.findAttributes(Attributes.sourceFile()).forEach(clb::with);
@ -145,8 +145,8 @@ public abstract class StateMachineBuilder {
handlers.add(handler.apply(this, cob));
}
}
// if(handlers.isEmpty() && stateSwitchCases.isEmpty())
// throw new RuntimeException("Not a state machine");
if(handlers.isEmpty())
throw new RuntimeException("Not a state machine");
cob.aload(0).getfield(CD_this, STATE_NAME, TypeKind.INT.upperBound()).lookupswitch(invalidState, stateSwitchCases);
var start = cob.startLabel();
var end = cob.newLabel();

View file

@ -24,6 +24,8 @@ public class FutureSMBuilder extends StateMachineBuilder {
public final static MethodTypeDesc MTD_Object_Waker = MethodTypeDesc.of(ConstantDescs.CD_Object, CD_Waker);
public final static MethodTypeDesc MTD_Obj = MethodTypeDesc.of(ConstantDescs.CD_Object);
public final static String AWAITING_FIELD_NAME = "awaiting";
static class AwaitHandler implements SpecialMethodHandler{
final int yield_state;
final Label yield_label;
@ -36,18 +38,19 @@ public class FutureSMBuilder extends StateMachineBuilder {
@Override
public void handle(StateMachineBuilder smb, CodeBuilder cob) {
System.out.println("Await");
cob.aload(0).loadConstant(yield_state).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound());
var start = cob.newBoundLabel();
cob.dup().dup()
.aload(1)
.invokeinterface(CD_Future, "poll", MTD_Object_Waker).dup()
cob.dup()
.aload(1).invokeinterface(CD_Future, "poll", MTD_Object_Waker).dup()
.instanceOf(CD_Pending);
cob.ifThenElse(bcb -> {
bcb.swap().aload(0).swap().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
smb.lt.savingLocals(smb.CD_this, bcb, () -> {
bcb.swap().aload(0).swap().putfield(smb.CD_this, "meow", CD_Future);
bcb.areturn().labelBinding(yield_label);
bcb.aload(0).getfield(smb.CD_this, "meow", CD_Future);
});
bcb.aload(0).getfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
bcb.aload(0).aconst_null().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
bcb.goto_(start);
}, bcb -> {
bcb.swap().pop();
@ -86,6 +89,7 @@ public class FutureSMBuilder extends StateMachineBuilder {
@Override
public void handle(StateMachineBuilder smb, CodeBuilder cob) {
System.out.println("Return");
cob.aload(0).loadConstant(-1).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()).areturn();
}
}
@ -102,7 +106,14 @@ public class FutureSMBuilder extends StateMachineBuilder {
cob.localVariable(1, "waker", CD_Waker, cob.startLabel(), cob.endLabel());
buildStateMachineMethodCode(clb, cob, 2);
}));
clb.withField("meow", CD_Future, ClassFile.ACC_PRIVATE);
clb.withMethod("cancel", MethodTypeDesc.of(ConstantDescs.CD_void), ClassFile.ACC_PUBLIC, mb -> mb.withCode(cob -> {
cob.aload(0).getfield(CD_this, AWAITING_FIELD_NAME, CD_Future).dup().ifThen(Opcode.IFNONNULL, boc -> {
boc.invokeinterface(CD_Future, "cancel", MethodTypeDesc.of(ConstantDescs.CD_void))
.aload(0).aconst_null().putfield(CD_this, AWAITING_FIELD_NAME, CD_Future).return_();
});
cob.pop().return_();
}));
clb.withField(AWAITING_FIELD_NAME, CD_Future, ClassFile.ACC_PRIVATE);
}
public FutureSMBuilder(ClassModel src_clm, MethodModel src_mem, CodeModel src_com) {