made progress

This commit is contained in:
Parker TenBroeck 2025-04-29 15:53:14 -04:00
parent 90bfb8a631
commit f52827f97b
6 changed files with 175 additions and 38 deletions

View file

@ -1,10 +1,11 @@
import async_example.Delay; import async_example.Delay;
import async_example.Jokio;
import async_example.Socket; import async_example.Socket;
import generator.future.Future; import generator.future.Future;
import generator.future.Waker; import generator.future.Waker;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public class Examples { public class Examples {
// public static Gen<String, Void> parse(String str){ // public static Gen<String, Void> parse(String str){
@ -83,10 +84,29 @@ public class Examples {
return Future.ret(value); return Future.ret(value);
} }
public Future<Void> send(ByteBuffer buffer, Socket socket){
String message = "hello world!\n";
buffer.limit(message.length()).put(message.getBytes(StandardCharsets.UTF_8)).position(0);
var wrote = socket.write_all(buffer).await();
buffer.clear().limit(wrote);
var read = socket.read_all(buffer).await();
System.out.println(new String(buffer.array(), 0, read));
return Future.ret(null);
}
public Future<String> awaitTest(int number){ public Future<String> awaitTest(int number){
var result = number(10).await()+number(20).await(); // var result = number(10).await()+number(20).await();
Jokio.runtime().await().spawn(awaitTest2(5000)); // Jokio.runtime().await().spawn(awaitTest2(5000));
return Future.ret(""+result);
var buffer = ByteBuffer.allocate(500);
try(var socket = Socket.connect(new InetSocketAddress("45.79.112.203", 4242)).await()){
send(buffer, socket).await();
} catch (Exception e) {
throw new RuntimeException(e);
}
return Future.ret("");
} }
public Future<String> closing(int number){ public Future<String> closing(int number){

View file

@ -5,48 +5,71 @@ import generator.future.Waker;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.ArrayDeque;
public class Socket implements AutoCloseable{ public class Socket implements AutoCloseable{
private final static Selector selector; private final static Selector SELECTOR;
private record ToRegister(SocketChannel sc, int ops, Waker waker){}
private final static ArrayDeque<ToRegister> to_register = new ArrayDeque<>();
static{ static{
try { try {
selector = Selector.open(); SELECTOR = Selector.open();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
new Thread(() -> { var thread = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()){ while(!Thread.currentThread().isInterrupted()){
try{ try{
selector.select(); synchronized (to_register){
var keys = selector.selectedKeys().iterator(); while(!to_register.isEmpty()){
var to = to_register.poll();
to.sc.register(SELECTOR, to.ops, to.waker);
}
}
SELECTOR.select();
var keys = SELECTOR.selectedKeys().iterator();
while (keys.hasNext()) { while (keys.hasNext()) {
SelectionKey key = keys.next(); SelectionKey key = keys.next();
keys.remove(); keys.remove();
var c = (SocketChannel)key.channel();
var w = (Waker)key.attachment();
System.out.println(key);
if (!key.isValid()) { if (!key.isValid()) {
}
}else if(key.isAcceptable()){ if(key.isAcceptable()){
}else if(key.isConnectable()){ }else if(key.isConnectable()){
c.finishConnect();
}else if(key.isReadable()){ }else if(key.isReadable()){
}else if(key.isWritable()){ }else if(key.isWritable()){
} }
w.wake();
} }
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
} }
} }
}).start(); });
thread.setName("Socket Polling Thread");
thread.setDaemon(true);
thread.start();
}
private static void register(SocketChannel sc, int ops, Waker waker){
synchronized (to_register){
to_register.add(new ToRegister(sc, ops, waker));
}
SELECTOR.wakeup();
} }
private final SocketChannel socket; private final SocketChannel socket;
@ -55,25 +78,84 @@ public class Socket implements AutoCloseable{
this.socket = sc; this.socket = sc;
} }
public static Future<Socket> bind(InetSocketAddress inet) throws IOException{ public static Future<Socket> connect(InetSocketAddress inet) {
var socket = SocketChannel.open();
return new Future<>() { return new Future<>() {
public SocketChannel socket;
@Override @Override
public Socket poll(Waker waker) { public Object poll(Waker waker) {
if(socket==null){
try{ try{
socket = SocketChannel.open();
socket.configureBlocking(false); socket.configureBlocking(false);
socket.socket().bind(new InetSocketAddress("localhost", 8080)); var connected = socket.connect(inet);
socket.register(selector, SelectionKey.OP_ACCEPT | SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE); if(!connected) {
return new Socket(socket); register(socket, SelectionKey.OP_CONNECT, waker);
return Pending.INSTANCE;
}
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
if(socket.isConnected()) return new Socket(socket);
return Pending.INSTANCE;
}
@Override @Override
public void cancel() { public void cancel() {
try { try {
socket.close(); if(socket!=null) socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
public Future<Integer> write_all(ByteBuffer buffer){
return new Future<>() {
int wrote = 0;
@Override
public Object poll(Waker waker) {
try {
wrote += socket.write(buffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
if(!buffer.hasRemaining()) return wrote;
register(socket, SelectionKey.OP_WRITE, waker);
return Pending.INSTANCE;
}
@Override
public void cancel() {
try {
if(socket!=null) socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
public Future<Integer> read_all(ByteBuffer buffer){
return new Future<>() {
int read = 0;
@Override
public Object poll(Waker waker) {
try {
read += socket.read(buffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
if(!buffer.hasRemaining()) return read;
register(socket, SelectionKey.OP_READ, waker);
return Pending.INSTANCE;
}
@Override
public void cancel() {
try {
if(socket!=null) socket.close();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -2,6 +2,7 @@ package generator.runtime;
import java.lang.classfile.CodeBuilder; import java.lang.classfile.CodeBuilder;
import java.lang.classfile.TypeKind; import java.lang.classfile.TypeKind;
import java.lang.constant.ConstantDescs;
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) {
@ -16,6 +17,7 @@ public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack) {
for (var entry : locals) { for (var entry : locals) {
slot++; slot++;
if (slot <= loc_off) continue; if (slot <= loc_off) continue;
if (entry.isCategory2_2nd()) continue; if (entry.isCategory2_2nd()) continue;
sst.save_local(smb, cob, entry.toCD(), slot - smb.paramSlotOff + loc_off - 1); sst.save_local(smb, cob, entry.toCD(), slot - smb.paramSlotOff + loc_off - 1);

View file

@ -7,7 +7,11 @@ import java.lang.classfile.attribute.StackMapFrameInfo;
import java.lang.classfile.attribute.StackMapTableAttribute; import java.lang.classfile.attribute.StackMapTableAttribute;
import java.lang.classfile.instruction.*; import java.lang.classfile.instruction.*;
import java.lang.constant.ClassDesc; import java.lang.constant.ClassDesc;
import java.lang.constant.DynamicConstantDesc;
import java.lang.constant.MethodHandleDesc;
import java.lang.constant.MethodTypeDesc;
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;
@ -310,10 +314,29 @@ public class FrameTracker {
case BranchInstruction b when b.opcode() == Opcode.GOTO || b.opcode() == Opcode.GOTO_W -> {} case BranchInstruction b when b.opcode() == Opcode.GOTO || b.opcode() == Opcode.GOTO_W -> {}
case BranchInstruction b -> popStack(); case BranchInstruction b -> popStack();
case ConstantInstruction c when ins.opcode() == Opcode.ACONST_NULL -> pushStack(Type.NULL_TYPE); case ConstantInstruction c when ins.opcode() == Opcode.ACONST_NULL -> pushStack(Type.NULL_TYPE);
case ConstantInstruction c -> pushStack(c.typeKind().upperBound()); case ConstantInstruction c -> {
switch(c.constantValue()){
case Double _ -> pushStack(Type.DOUBLE_TYPE);
case Float _ -> pushStack(Type.FLOAT_TYPE);
case Integer _ -> pushStack(Type.INTEGER_TYPE);
case Long _ -> pushStack(Type.LONG_TYPE);
case String _ -> pushStack(Type.STRING_TYPE);
case ClassDesc desc -> pushStack(desc);
case DynamicConstantDesc dynamicConstantDesc -> pushStack(dynamicConstantDesc.constantType());
case MethodHandleDesc methodHandleDesc ->
throw new RuntimeException();
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());
case FieldInstruction f -> { case FieldInstruction f -> {
switch(f.opcode()){
case GETFIELD -> decStack(1).pushStack(f.typeSymbol());
case GETSTATIC -> pushStack(f.typeSymbol());
case PUTFIELD -> decStack(1 + TypeKind.from(f.typeSymbol()).slotSize());
case PUTSTATIC -> decStack(TypeKind.from(f.typeSymbol()).slotSize());
}
} }
case IncrementInstruction i -> {} case IncrementInstruction i -> {}
case InvokeDynamicInstruction i -> { case InvokeDynamicInstruction i -> {
@ -334,6 +357,9 @@ public class FrameTracker {
case InvokeInstruction i -> { case InvokeInstruction i -> {
for(var param : i.typeSymbol().parameterArray()) for(var param : i.typeSymbol().parameterArray())
decStack(TypeKind.from(param).slotSize()); decStack(TypeKind.from(param).slotSize());
if(stack.isEmpty()){
System.out.println(Arrays.toString(i.typeSymbol().parameterArray()));
}
popStack(); popStack();
pushStack(i.typeSymbol().returnType()); pushStack(i.typeSymbol().returnType());
} }
@ -449,8 +475,16 @@ public class FrameTracker {
locals.clear(); locals.clear();
for( var sl : tmp.stack()) for( var sl : tmp.stack())
pushStack(Type.verificationType(sl)); pushStack(Type.verificationType(sl));
for( var local : tmp.locals())
locals.add(Type.verificationType(local)); for( var sl : tmp.locals())
locals.add(Type.verificationType(sl));
// while(locals.size()>tmp.locals().size())locals.removeLast();
// while(locals.size()<tmp.locals().size())locals.add(null);
// int slot = 0;
// for( var local : tmp.locals()){
// locals.set(slot, Type.verificationType(local));
// }
} }
} }
} }

View file

@ -25,7 +25,7 @@ public class SavedStateTracker {
} }
var s = new StackState(name, desc); var s = new StackState(name, desc);
saved.addLast(s); saved.add(s);
return s; return s;
} }
@ -53,6 +53,6 @@ public class SavedStateTracker {
public void restore_all(StateMachineBuilder smb, CodeBuilder cob) { public void restore_all(StateMachineBuilder smb, CodeBuilder cob) {
while(!saved.isEmpty()) while(!saved.isEmpty())
restore(smb, cob, saved.getFirst()); restore(smb, cob, saved.getLast());
} }
} }

View file

@ -70,18 +70,17 @@ public abstract class StateMachineBuilder {
this.paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum(); this.paramSlotOff = Arrays.stream(params).mapToInt(p -> TypeKind.from(p).slotSize()).sum();
System.out.println("FRAME");
var lt = new FrameTracker(this, src_com); var lt = new FrameTracker(this, src_com);
for(var coe : src_com){ for(var coe : src_com){
if(coe instanceof Instruction) if(coe instanceof Instruction) {
frames.add(new Frame(lt.locals(), lt.stack())); frames.add(new Frame(lt.locals(), lt.stack()));
System.out.println(frames.getLast() + " " + coe);
}
lt.encounter(coe); lt.encounter(coe);
} }
frames.add(new Frame(lt.locals(), lt.stack())); frames.add(new Frame(lt.locals(), lt.stack()));
for(var wf : with_frames()){
if(wf.coe instanceof Instruction)
System.out.println(wf.coe() + " " + wf.frame());
}
} }
public record WithFrame(CodeElement coe, Frame frame){} public record WithFrame(CodeElement coe, Frame frame){}