Compare commits
No commits in common. "d22e4b06112b7858bf9e310eb213e08fb0997419" and "d7677d7941d5bbdc8a4ec4ce739f46514633d9aa" have entirely different histories.
d22e4b0611
...
d7677d7941
3
Makefile
3
Makefile
@ -20,8 +20,7 @@ IR_OBJECTS = $(IR_SOURCES:.c=.o)
|
||||
GC_SOURCES = runtime/gc/gc.c runtime/gc/gc_heap.c runtime/gc/gc_mark.c runtime/gc/gc_sweep.c runtime/gc/gc_roots.c
|
||||
GC_OBJECTS = $(GC_SOURCES:.c=.o)
|
||||
|
||||
RUNTIME_CORE_SOURCES = runtime/runtime_value.c runtime/runtime_stack.c runtime/runtime_static.c runtime/runtime_exception.c runtime/runtime_intern.c runtime/runtime_lookup.c
|
||||
RUNTIME_SOURCES = runtime/runtime.c $(RUNTIME_CORE_SOURCES) runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c $(GC_SOURCES)
|
||||
RUNTIME_SOURCES = runtime/runtime.c runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c $(GC_SOURCES)
|
||||
RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o)
|
||||
|
||||
LOADER_SOURCES = loader/loader.c
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
public class ComprehensiveSocketExample {
|
||||
public static void testInetAddress() {
|
||||
System.out.println("\n--- InetAddress Tests ---");
|
||||
|
||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||
System.out.println("Loopback address: " + loopback.getHostAddress());
|
||||
System.out.println("Is loopback: " + loopback.isLoopbackAddress());
|
||||
System.out.println("Is multicast: " + loopback.isMulticastAddress());
|
||||
|
||||
InetAddress localhost = InetAddress.getByName("localhost");
|
||||
System.out.println("Localhost: " + localhost.getHostName());
|
||||
System.out.println("Localhost IP: " + localhost.getHostAddress());
|
||||
|
||||
int reachable = localhost.isReachable(1000) ? 1 : 0;
|
||||
System.out.println("Localhost reachable: " + reachable);
|
||||
|
||||
InetAddress.getAllByName("localhost");
|
||||
localhost.getAddress();
|
||||
System.out.println("InetAddress methods executed");
|
||||
}
|
||||
|
||||
public static void testServerSocket() {
|
||||
System.out.println("\n--- ServerSocket Tests ---");
|
||||
|
||||
ServerSocket server = new ServerSocket(0);
|
||||
int port = server.getLocalPort();
|
||||
System.out.println("Server port: " + port);
|
||||
|
||||
int bound = server.isBound() ? 1 : 0;
|
||||
System.out.println("Server is bound: " + bound);
|
||||
|
||||
int closed = server.isClosed() ? 1 : 0;
|
||||
System.out.println("Server is closed: " + closed);
|
||||
|
||||
server.setSoTimeout(5000);
|
||||
int timeout = server.getSoTimeout();
|
||||
System.out.println("Server timeout: " + timeout);
|
||||
|
||||
server.setReceiveBufferSize(16384);
|
||||
int bufSize = server.getReceiveBufferSize();
|
||||
System.out.println("Receive buffer size: " + bufSize);
|
||||
|
||||
server.setReuseAddress(true);
|
||||
int reuse = server.getReuseAddress() ? 1 : 0;
|
||||
System.out.println("Reuse address enabled: " + reuse);
|
||||
|
||||
System.out.println("ServerSocket configured successfully");
|
||||
}
|
||||
|
||||
public static void testSocketOptions() {
|
||||
System.out.println("\n--- Socket Options Tests ---");
|
||||
|
||||
Socket sock = new Socket();
|
||||
|
||||
sock.setSoTimeout(3000);
|
||||
int timeout = sock.getSoTimeout();
|
||||
System.out.println("Socket timeout: " + timeout);
|
||||
|
||||
sock.setTcpNoDelay(true);
|
||||
int nodelay = sock.getTcpNoDelay() ? 1 : 0;
|
||||
System.out.println("TCP NoDelay: " + nodelay);
|
||||
|
||||
sock.setSendBufferSize(8192);
|
||||
int sendBuf = sock.getSendBufferSize();
|
||||
System.out.println("Send buffer: " + sendBuf);
|
||||
|
||||
sock.setReceiveBufferSize(8192);
|
||||
int recvBuf = sock.getReceiveBufferSize();
|
||||
System.out.println("Receive buffer: " + recvBuf);
|
||||
|
||||
sock.setKeepAlive(true);
|
||||
int keepAlive = sock.getKeepAlive() ? 1 : 0;
|
||||
System.out.println("Keep alive: " + keepAlive);
|
||||
|
||||
sock.setReuseAddress(true);
|
||||
int reuse = sock.getReuseAddress() ? 1 : 0;
|
||||
System.out.println("Reuse address: " + reuse);
|
||||
|
||||
int connected = sock.isConnected() ? 1 : 0;
|
||||
System.out.println("Socket connected: " + connected);
|
||||
|
||||
int sockClosed = sock.isClosed() ? 1 : 0;
|
||||
System.out.println("Socket closed: " + sockClosed);
|
||||
|
||||
sock.close();
|
||||
System.out.println("Socket options configured successfully");
|
||||
}
|
||||
|
||||
public static int main() {
|
||||
System.out.println("========================================");
|
||||
System.out.println("Comprehensive Socket API Example");
|
||||
System.out.println("========================================");
|
||||
|
||||
testInetAddress();
|
||||
testServerSocket();
|
||||
testSocketOptions();
|
||||
|
||||
System.out.println("========================================");
|
||||
System.out.println("All Socket API tests completed successfully");
|
||||
System.out.println("========================================");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
public class InetAddressExample {
|
||||
public static int main() {
|
||||
System.out.println("InetAddress Methods Example");
|
||||
System.out.println("============================");
|
||||
|
||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||
System.out.println("Loopback: " + loopback.getHostAddress());
|
||||
System.out.println("Is loopback: " + loopback.isLoopbackAddress());
|
||||
System.out.println("Is multicast: " + loopback.isMulticastAddress());
|
||||
|
||||
InetAddress localhost = InetAddress.getByName("localhost");
|
||||
System.out.println("Localhost: " + localhost.getHostName());
|
||||
System.out.println("Localhost address: " + localhost.getHostAddress());
|
||||
|
||||
System.out.println("Testing reachability...");
|
||||
int reachable = localhost.isReachable(1000) ? 1 : 0;
|
||||
System.out.println("Localhost reachable: " + reachable);
|
||||
|
||||
System.out.println("Getting all addresses for localhost...");
|
||||
InetAddress.getAllByName("localhost");
|
||||
|
||||
System.out.println("Getting byte address...");
|
||||
localhost.getAddress();
|
||||
|
||||
System.out.println("InetAddress tests completed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
public class SimpleHttpClient {
|
||||
public static int main() {
|
||||
System.out.println("=================================");
|
||||
System.out.println("Rava HTTP Client Example");
|
||||
System.out.println("=================================");
|
||||
System.out.println("");
|
||||
|
||||
String host = "127.0.0.1";
|
||||
int port = 8080;
|
||||
|
||||
System.out.println("Connecting to " + host + ":" + port);
|
||||
|
||||
Socket socket = new Socket(host, port);
|
||||
System.out.println("Connected successfully");
|
||||
|
||||
InputStream in = socket.getInputStream();
|
||||
OutputStream out = socket.getOutputStream();
|
||||
|
||||
System.out.println("");
|
||||
System.out.println("Sending HTTP GET request...");
|
||||
out.write("GET / HTTP/1.1\r\n");
|
||||
out.write("Host: localhost\r\n");
|
||||
out.write("Connection: close\r\n");
|
||||
out.write("\r\n");
|
||||
out.flush();
|
||||
|
||||
System.out.println("Request sent, reading response...");
|
||||
System.out.println("");
|
||||
System.out.println("--- HTTP Response ---");
|
||||
|
||||
int bytesRead = 0;
|
||||
int maxBytes = 1000;
|
||||
while (bytesRead < maxBytes) {
|
||||
int ch = in.read();
|
||||
if (ch < 0) {
|
||||
break;
|
||||
}
|
||||
System.out.print((char)ch);
|
||||
bytesRead = bytesRead + 1;
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
System.out.println("--- End of Response ---");
|
||||
System.out.println("");
|
||||
|
||||
socket.close();
|
||||
System.out.println("Connection closed");
|
||||
System.out.println("");
|
||||
System.out.println("HTTP client example completed successfully!");
|
||||
System.out.println("Total bytes received: " + bytesRead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
public class SimpleHttpServer {
|
||||
public static int main() {
|
||||
int port = 8080;
|
||||
System.out.println("=================================");
|
||||
System.out.println("Rava HTTP Server Example");
|
||||
System.out.println("=================================");
|
||||
System.out.println("");
|
||||
System.out.println("Starting HTTP server on port " + port);
|
||||
|
||||
ServerSocket server = new ServerSocket(port);
|
||||
server.setReuseAddress(true);
|
||||
|
||||
System.out.println("Server listening on http://localhost:" + port);
|
||||
System.out.println("Send an HTTP request to see the response");
|
||||
System.out.println("");
|
||||
System.out.println("Example:");
|
||||
System.out.println(" curl http://localhost:8080/");
|
||||
System.out.println(" or visit http://localhost:8080/ in your browser");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Waiting for connection...");
|
||||
Socket client = server.accept();
|
||||
System.out.println("Connection accepted!");
|
||||
|
||||
InputStream in = client.getInputStream();
|
||||
OutputStream out = client.getOutputStream();
|
||||
|
||||
System.out.println("Reading request...");
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < 100) {
|
||||
int ch = in.read();
|
||||
if (ch < 0) {
|
||||
break;
|
||||
}
|
||||
bytesRead = bytesRead + 1;
|
||||
}
|
||||
|
||||
System.out.println("Sending response...");
|
||||
out.write("HTTP/1.1 200 OK\r\n");
|
||||
out.write("Content-Type: text/html\r\n");
|
||||
out.write("Connection: close\r\n");
|
||||
out.write("\r\n");
|
||||
out.write("<html>\n");
|
||||
out.write("<head><title>Rava HTTP Server</title></head>\n");
|
||||
out.write("<body style=\"font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px;\">\n");
|
||||
out.write("<h1 style=\"color: #333;\">Hello from Rava!</h1>\n");
|
||||
out.write("<p>This is a simple HTTP server written in Java and running on the <b>Rava</b> Java interpreter.</p>\n");
|
||||
out.write("<h2>Features Demonstrated:</h2>\n");
|
||||
out.write("<ul>\n");
|
||||
out.write("<li>ServerSocket - listening for connections</li>\n");
|
||||
out.write("<li>Socket - accepting client connections</li>\n");
|
||||
out.write("<li>InputStream - reading HTTP requests</li>\n");
|
||||
out.write("<li>OutputStream - sending HTTP responses</li>\n");
|
||||
out.write("</ul>\n");
|
||||
out.write("<hr>\n");
|
||||
out.write("<p><small>Powered by <b>Rava</b> - A Java interpreter written in C</small></p>\n");
|
||||
out.write("</body>\n");
|
||||
out.write("</html>\n");
|
||||
out.flush();
|
||||
|
||||
System.out.println("Response sent successfully");
|
||||
|
||||
client.close();
|
||||
server.close();
|
||||
|
||||
System.out.println("");
|
||||
System.out.println("Server shut down");
|
||||
System.out.println("HTTP server example completed successfully!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
public class SocketBindDebug {
|
||||
public static int main() {
|
||||
Socket sock = new Socket();
|
||||
System.out.print("Before bind, isBound: ");
|
||||
System.out.println(sock.isBound());
|
||||
|
||||
sock.bind("0.0.0.0", 8888);
|
||||
|
||||
System.out.print("After bind, isBound: ");
|
||||
boolean bound = sock.isBound();
|
||||
System.out.println(bound);
|
||||
|
||||
sock.close();
|
||||
|
||||
return bound ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
public class SocketBindExample {
|
||||
public static int main() {
|
||||
System.out.println("Socket Bind Example");
|
||||
System.out.println("==================");
|
||||
|
||||
Socket sock = new Socket();
|
||||
|
||||
System.out.print("Socket bound before bind(): ");
|
||||
System.out.println(sock.isBound());
|
||||
|
||||
sock.bind("127.0.0.1", 8888);
|
||||
|
||||
System.out.print("Socket bound after bind(): ");
|
||||
System.out.println(sock.isBound());
|
||||
|
||||
sock.close();
|
||||
|
||||
System.out.println("Socket bind example completed successfully");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
public class SocketBufferSizeExample {
|
||||
public static int main() {
|
||||
System.out.println("Socket Buffer Size Example");
|
||||
System.out.println("==========================");
|
||||
|
||||
Socket sock = new Socket();
|
||||
|
||||
System.out.print("Initial send buffer size: ");
|
||||
System.out.println(sock.getSendBufferSize());
|
||||
|
||||
System.out.print("Initial receive buffer size: ");
|
||||
System.out.println(sock.getReceiveBufferSize());
|
||||
|
||||
System.out.println("\nSetting buffer sizes to 32KB...");
|
||||
sock.setSendBufferSize(32768);
|
||||
sock.setReceiveBufferSize(32768);
|
||||
|
||||
System.out.print("New send buffer size: ");
|
||||
System.out.println(sock.getSendBufferSize());
|
||||
|
||||
System.out.print("New receive buffer size: ");
|
||||
System.out.println(sock.getReceiveBufferSize());
|
||||
|
||||
sock.close();
|
||||
|
||||
System.out.println("\nBuffer size configuration completed successfully");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
public class SocketLifecycleExample {
|
||||
public static int main() {
|
||||
System.out.println("Socket Lifecycle Example");
|
||||
System.out.println("========================");
|
||||
|
||||
Socket client = new Socket();
|
||||
|
||||
System.out.println("\nInitial state:");
|
||||
System.out.print(" Connected: ");
|
||||
System.out.println(client.isConnected());
|
||||
System.out.print(" Closed: ");
|
||||
System.out.println(client.isClosed());
|
||||
System.out.print(" Bound: ");
|
||||
System.out.println(client.isBound());
|
||||
|
||||
System.out.println("\nBinding socket to local address...");
|
||||
client.bind("127.0.0.1", 6666);
|
||||
|
||||
System.out.print(" Bound: ");
|
||||
System.out.println(client.isBound());
|
||||
|
||||
System.out.println("\nCreating server and connecting...");
|
||||
ServerSocket server = new ServerSocket(6667);
|
||||
InetAddress addr = InetAddress.getLoopbackAddress();
|
||||
client.connect(addr, 6667);
|
||||
|
||||
System.out.print(" Connected: ");
|
||||
System.out.println(client.isConnected());
|
||||
|
||||
System.out.println("\nShutdown state:");
|
||||
System.out.print(" Input shutdown: ");
|
||||
System.out.println(client.isInputShutdown());
|
||||
System.out.print(" Output shutdown: ");
|
||||
System.out.println(client.isOutputShutdown());
|
||||
|
||||
System.out.println("\nPerforming half-close (shutdown output)...");
|
||||
client.shutdownOutput();
|
||||
|
||||
System.out.print(" Output shutdown: ");
|
||||
System.out.println(client.isOutputShutdown());
|
||||
System.out.print(" Still connected: ");
|
||||
System.out.println(client.isConnected());
|
||||
|
||||
System.out.println("\nClosing socket...");
|
||||
client.close();
|
||||
|
||||
System.out.print(" Closed: ");
|
||||
System.out.println(client.isClosed());
|
||||
|
||||
server.close();
|
||||
|
||||
System.out.println("\nSocket lifecycle example completed successfully");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
public class SocketOptionsExample {
|
||||
public static int main() {
|
||||
Socket socket = new Socket();
|
||||
|
||||
System.out.println("Socket Options Example");
|
||||
System.out.println("=====================");
|
||||
|
||||
System.out.print("Initial KeepAlive: ");
|
||||
System.out.println(socket.getKeepAlive());
|
||||
|
||||
socket.setKeepAlive(true);
|
||||
System.out.print("After setKeepAlive(true): ");
|
||||
System.out.println(socket.getKeepAlive());
|
||||
|
||||
socket.setKeepAlive(false);
|
||||
System.out.print("After setKeepAlive(false): ");
|
||||
System.out.println(socket.getKeepAlive());
|
||||
|
||||
System.out.print("Initial ReuseAddress: ");
|
||||
System.out.println(socket.getReuseAddress());
|
||||
|
||||
socket.setReuseAddress(true);
|
||||
System.out.print("After setReuseAddress(true): ");
|
||||
System.out.println(socket.getReuseAddress());
|
||||
|
||||
socket.setReuseAddress(false);
|
||||
System.out.print("After setReuseAddress(false): ");
|
||||
System.out.println(socket.getReuseAddress());
|
||||
|
||||
socket.setSendBufferSize(32768);
|
||||
System.out.print("Send buffer size: ");
|
||||
System.out.println(socket.getSendBufferSize());
|
||||
|
||||
socket.setReceiveBufferSize(32768);
|
||||
System.out.print("Receive buffer size: ");
|
||||
System.out.println(socket.getReceiveBufferSize());
|
||||
|
||||
socket.close();
|
||||
System.out.println("Socket closed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,146 +0,0 @@
|
||||
public class SocketPerformanceBenchmark {
|
||||
public static int main() {
|
||||
System.out.println("================================================");
|
||||
System.out.println("Socket API Performance Benchmark");
|
||||
System.out.println("================================================");
|
||||
System.out.println("");
|
||||
System.out.println("This benchmark measures Socket API operations");
|
||||
System.out.println("to demonstrate networking performance in Rava.");
|
||||
System.out.println("");
|
||||
|
||||
int iterations = 10;
|
||||
|
||||
System.out.println("Test 1: ServerSocket Creation and Binding");
|
||||
System.out.println("------------------------------------------");
|
||||
long start1 = System.currentTimeMillis();
|
||||
int i = 0;
|
||||
while (i < iterations) {
|
||||
ServerSocket server = new ServerSocket(0);
|
||||
int port = server.getLocalPort();
|
||||
server.close();
|
||||
i = i + 1;
|
||||
}
|
||||
long end1 = System.currentTimeMillis();
|
||||
long time1 = end1 - start1;
|
||||
System.out.println("Created and closed " + iterations + " ServerSockets in " + time1 + "ms");
|
||||
if (time1 > 0) {
|
||||
long avg1 = time1 / iterations;
|
||||
System.out.println("Average: " + avg1 + "ms per ServerSocket");
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 2: Socket Object Creation");
|
||||
System.out.println("-------------------------------");
|
||||
long start2 = System.currentTimeMillis();
|
||||
int j = 0;
|
||||
while (j < iterations) {
|
||||
Socket sock = new Socket();
|
||||
sock.close();
|
||||
j = j + 1;
|
||||
}
|
||||
long end2 = System.currentTimeMillis();
|
||||
long time2 = end2 - start2;
|
||||
System.out.println("Created and closed " + iterations + " Sockets in " + time2 + "ms");
|
||||
if (time2 > 0) {
|
||||
long avg2 = time2 / iterations;
|
||||
System.out.println("Average: " + avg2 + "ms per Socket");
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 3: Socket Option Configuration");
|
||||
System.out.println("------------------------------------");
|
||||
long start3 = System.currentTimeMillis();
|
||||
int k = 0;
|
||||
while (k < iterations) {
|
||||
Socket socket = new Socket();
|
||||
socket.setKeepAlive(true);
|
||||
socket.setTcpNoDelay(true);
|
||||
socket.setReuseAddress(true);
|
||||
socket.setSendBufferSize(8192);
|
||||
socket.setReceiveBufferSize(8192);
|
||||
|
||||
int keepAlive = socket.getKeepAlive() ? 1 : 0;
|
||||
int noDelay = socket.getTcpNoDelay() ? 1 : 0;
|
||||
int reuse = socket.getReuseAddress() ? 1 : 0;
|
||||
int sendBuf = socket.getSendBufferSize();
|
||||
int recvBuf = socket.getReceiveBufferSize();
|
||||
|
||||
socket.close();
|
||||
k = k + 1;
|
||||
}
|
||||
long end3 = System.currentTimeMillis();
|
||||
long time3 = end3 - start3;
|
||||
System.out.println("Configured " + iterations + " Sockets with 5 options in " + time3 + "ms");
|
||||
if (time3 > 0) {
|
||||
long avg3 = time3 / iterations;
|
||||
System.out.println("Average: " + avg3 + "ms per Socket configuration");
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 4: InetAddress Resolution");
|
||||
System.out.println("-------------------------------");
|
||||
long start4 = System.currentTimeMillis();
|
||||
int m = 0;
|
||||
while (m < iterations) {
|
||||
InetAddress local = InetAddress.getLoopbackAddress();
|
||||
InetAddress localhost = InetAddress.getByName("localhost");
|
||||
String host = localhost.getHostName();
|
||||
String addr = localhost.getHostAddress();
|
||||
int isLoop = localhost.isLoopbackAddress() ? 1 : 0;
|
||||
m = m + 1;
|
||||
}
|
||||
long end4 = System.currentTimeMillis();
|
||||
long time4 = end4 - start4;
|
||||
System.out.println("Resolved " + iterations + " InetAddresses in " + time4 + "ms");
|
||||
if (time4 > 0) {
|
||||
long avg4 = time4 / iterations;
|
||||
System.out.println("Average: " + avg4 + "ms per resolution");
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 5: ServerSocket Options");
|
||||
System.out.println("-----------------------------");
|
||||
long start5 = System.currentTimeMillis();
|
||||
int n = 0;
|
||||
while (n < iterations) {
|
||||
ServerSocket srv = new ServerSocket(0);
|
||||
srv.setReuseAddress(true);
|
||||
srv.setReceiveBufferSize(16384);
|
||||
srv.setSoTimeout(5000);
|
||||
|
||||
int reuseAddr = srv.getReuseAddress() ? 1 : 0;
|
||||
int bufferSize = srv.getReceiveBufferSize();
|
||||
int socketTimeout = srv.getSoTimeout();
|
||||
|
||||
srv.close();
|
||||
n = n + 1;
|
||||
}
|
||||
long end5 = System.currentTimeMillis();
|
||||
long time5 = end5 - start5;
|
||||
System.out.println("Configured " + iterations + " ServerSockets in " + time5 + "ms");
|
||||
if (time5 > 0) {
|
||||
long avg5 = time5 / iterations;
|
||||
System.out.println("Average: " + avg5 + "ms per ServerSocket");
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
long totalTime = time1 + time2 + time3 + time4 + time5;
|
||||
int totalOps = iterations * 5;
|
||||
|
||||
System.out.println("================================================");
|
||||
System.out.println("Summary");
|
||||
System.out.println("================================================");
|
||||
System.out.println("Total operations: " + totalOps);
|
||||
System.out.println("Total time: " + totalTime + "ms");
|
||||
if (totalTime > 0) {
|
||||
long avgOp = totalTime / totalOps;
|
||||
long opsPerSec = (totalOps * 1000) / totalTime;
|
||||
System.out.println("Average time per operation: " + avgOp + "ms");
|
||||
System.out.println("Operations per second: " + opsPerSec);
|
||||
}
|
||||
System.out.println("");
|
||||
System.out.println("Benchmark completed successfully!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
public class SocketShutdownExample {
|
||||
public static int main() {
|
||||
System.out.println("Socket Graceful Shutdown Example");
|
||||
System.out.println("=================================");
|
||||
|
||||
ServerSocket server = new ServerSocket(7777);
|
||||
Socket client = new Socket();
|
||||
InetAddress addr = InetAddress.getLoopbackAddress();
|
||||
|
||||
client.connect(addr, 7777);
|
||||
|
||||
System.out.print("Input shutdown: ");
|
||||
System.out.println(client.isInputShutdown());
|
||||
|
||||
System.out.print("Output shutdown: ");
|
||||
System.out.println(client.isOutputShutdown());
|
||||
|
||||
System.out.println("\nShutting down input...");
|
||||
client.shutdownInput();
|
||||
|
||||
System.out.print("Input shutdown after shutdownInput(): ");
|
||||
System.out.println(client.isInputShutdown());
|
||||
|
||||
System.out.println("\nShutting down output...");
|
||||
client.shutdownOutput();
|
||||
|
||||
System.out.print("Output shutdown after shutdownOutput(): ");
|
||||
System.out.println(client.isOutputShutdown());
|
||||
|
||||
client.close();
|
||||
server.close();
|
||||
|
||||
System.out.println("\nGraceful shutdown example completed successfully");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
public class StreamMethodsExample {
|
||||
public static int main() {
|
||||
System.out.println("Stream Methods Example");
|
||||
System.out.println("======================");
|
||||
|
||||
System.out.println("Stream methods flush() and skip() are now available");
|
||||
System.out.println("These methods work with InputStream and OutputStream");
|
||||
System.out.println("obtained from Socket connections.");
|
||||
|
||||
System.out.println("\nExample usage:");
|
||||
System.out.println(" InputStream in = socket.getInputStream();");
|
||||
System.out.println(" long skipped = in.skip(100); // Skip 100 bytes");
|
||||
System.out.println(" ");
|
||||
System.out.println(" OutputStream out = socket.getOutputStream();");
|
||||
System.out.println(" out.write(data);");
|
||||
System.out.println(" out.flush(); // Flush buffered data");
|
||||
|
||||
System.out.println("\nStream methods implementation complete!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
public class StringErrorHandlingTest {
|
||||
public static int main() {
|
||||
System.out.println("===========================================");
|
||||
System.out.println("String Error Handling & Edge Cases Test");
|
||||
System.out.println("===========================================");
|
||||
System.out.println("");
|
||||
|
||||
String test = "Hello";
|
||||
System.out.println("Test string: \"" + test + "\" (length: " + test.length() + ")");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 1: charAt() with out of bounds index");
|
||||
System.out.println("Trying charAt(10) on string of length 5...");
|
||||
char outOfBounds = test.charAt(10);
|
||||
System.out.println("Result: " + outOfBounds);
|
||||
System.out.println("(Should handle gracefully or throw error)");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 2: charAt() with negative index");
|
||||
System.out.println("Trying charAt(-1)...");
|
||||
char negative = test.charAt(-1);
|
||||
System.out.println("Result: " + negative);
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 3: substring() with invalid range");
|
||||
System.out.println("Trying substring(3, 1) (end before start)...");
|
||||
String badRange = test.substring(3, 1);
|
||||
System.out.println("Result: \"" + badRange + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 4: substring() with out of bounds end");
|
||||
System.out.println("Trying substring(0, 100)...");
|
||||
String badEnd = test.substring(0, 100);
|
||||
System.out.println("Result: \"" + badEnd + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 5: substring() with negative indices");
|
||||
System.out.println("Trying substring(-1, 3)...");
|
||||
String negStart = test.substring(-1, 3);
|
||||
System.out.println("Result: \"" + negStart + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 6: indexOf() with empty string");
|
||||
System.out.println("Trying indexOf(\"\")...");
|
||||
int emptyIdx = test.indexOf("");
|
||||
System.out.println("Result: " + emptyIdx);
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 7: Empty string operations");
|
||||
String empty = "";
|
||||
System.out.println("Empty string length: " + empty.length());
|
||||
System.out.println("Empty equals empty: " + (empty.equals("") ? "true" : "false"));
|
||||
System.out.println("Empty contains empty: " + (empty.contains("") ? "true" : "false"));
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Test 8: String with special characters");
|
||||
String special = "Hello\nWorld\t!";
|
||||
System.out.println("String with newline and tab:");
|
||||
System.out.println(" Length: " + special.length());
|
||||
System.out.println(" indexOf(\"\\n\"): " + special.indexOf("\n"));
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("===========================================");
|
||||
System.out.println("Error handling test complete");
|
||||
System.out.println("===========================================");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
public class StringMethodsDemo {
|
||||
public static int main() {
|
||||
System.out.println("==========================================");
|
||||
System.out.println("String Methods Demonstration");
|
||||
System.out.println("==========================================");
|
||||
System.out.println("");
|
||||
|
||||
String original = "Hello World";
|
||||
System.out.println("Original string: \"" + original + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("1. length() - Get string length");
|
||||
int len = original.length();
|
||||
System.out.println(" Length: " + len);
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("2. charAt(index) - Get character at position");
|
||||
char first = original.charAt(0);
|
||||
char space = original.charAt(5);
|
||||
char last = original.charAt(10);
|
||||
System.out.println(" charAt(0): " + first + " (H)");
|
||||
System.out.println(" charAt(5): " + space + " (space)");
|
||||
System.out.println(" charAt(10): " + last + " (d)");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("3. substring(start, end) - Extract portion");
|
||||
String hello = original.substring(0, 5);
|
||||
String world = original.substring(6, 11);
|
||||
System.out.println(" substring(0, 5): \"" + hello + "\"");
|
||||
System.out.println(" substring(6, 11): \"" + world + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("4. equals(other) - Compare strings");
|
||||
String same = "Hello World";
|
||||
String different = "hello world";
|
||||
int eq1 = original.equals(same) ? 1 : 0;
|
||||
int eq2 = original.equals(different) ? 1 : 0;
|
||||
System.out.println(" equals(\"Hello World\"): " + (eq1 == 1 ? "true" : "false"));
|
||||
System.out.println(" equals(\"hello world\"): " + (eq2 == 1 ? "true" : "false"));
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("5. indexOf(substring) - Find position");
|
||||
int pos1 = original.indexOf("World");
|
||||
int pos2 = original.indexOf("xyz");
|
||||
System.out.println(" indexOf(\"World\"): " + pos1);
|
||||
System.out.println(" indexOf(\"xyz\"): " + pos2 + " (not found)");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("6. contains(substring) - Check if contains");
|
||||
int has1 = original.contains("World") ? 1 : 0;
|
||||
int has2 = original.contains("xyz") ? 1 : 0;
|
||||
System.out.println(" contains(\"World\"): " + (has1 == 1 ? "true" : "false"));
|
||||
System.out.println(" contains(\"xyz\"): " + (has2 == 1 ? "true" : "false"));
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("7. startsWith/endsWith - Check boundaries");
|
||||
int starts = original.startsWith("Hello") ? 1 : 0;
|
||||
int ends = original.endsWith("World") ? 1 : 0;
|
||||
System.out.println(" startsWith(\"Hello\"): " + (starts == 1 ? "true" : "false"));
|
||||
System.out.println(" endsWith(\"World\"): " + (ends == 1 ? "true" : "false"));
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("8. toLowerCase/toUpperCase - Case conversion");
|
||||
String lower = original.toLowerCase();
|
||||
String upper = original.toUpperCase();
|
||||
System.out.println(" toLowerCase(): \"" + lower + "\"");
|
||||
System.out.println(" toUpperCase(): \"" + upper + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("9. trim() - Remove whitespace");
|
||||
String padded = " Hello World ";
|
||||
String trimmed = padded.trim();
|
||||
System.out.println(" Original: \"" + padded + "\"");
|
||||
System.out.println(" Trimmed: \"" + trimmed + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("10. compareTo() - Lexicographic comparison");
|
||||
int cmp1 = original.compareTo("Hello World");
|
||||
int cmp2 = original.compareTo("ABC");
|
||||
int cmp3 = original.compareTo("XYZ");
|
||||
System.out.println(" compareTo(\"Hello World\"): " + cmp1 + " (equal)");
|
||||
System.out.println(" compareTo(\"ABC\"): " + (cmp2 > 0 ? "positive" : "negative") + " (after ABC)");
|
||||
System.out.println(" compareTo(\"XYZ\"): " + (cmp3 < 0 ? "negative" : "positive") + " (before XYZ)");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("11. String concatenation with +");
|
||||
String part1 = "Hello";
|
||||
String part2 = " ";
|
||||
String part3 = "World";
|
||||
String concat = part1 + part2 + part3;
|
||||
System.out.println(" \"" + part1 + "\" + \"" + part2 + "\" + \"" + part3 + "\" = \"" + concat + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("12. Concatenation with numbers");
|
||||
int num = 42;
|
||||
String withNum = "The answer is " + num;
|
||||
System.out.println(" \"The answer is \" + 42 = \"" + withNum + "\"");
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("==========================================");
|
||||
System.out.println("All String methods working correctly!");
|
||||
System.out.println("==========================================");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
44
ir/ir.c
44
ir/ir.c
@ -290,52 +290,8 @@ static const char* _rava_opcode_name(RavaOpCode_e opcode) {
|
||||
case RAVA_OP_SOCKET_GET_INPUT_STREAM: return "SOCKET_GET_INPUT_STREAM";
|
||||
case RAVA_OP_SOCKET_GET_OUTPUT_STREAM: return "SOCKET_GET_OUTPUT_STREAM";
|
||||
case RAVA_OP_INPUT_STREAM_READ: return "INPUT_STREAM_READ";
|
||||
case RAVA_OP_INPUT_STREAM_READ_BYTES: return "INPUT_STREAM_READ_BYTES";
|
||||
case RAVA_OP_INPUT_STREAM_AVAILABLE: return "INPUT_STREAM_AVAILABLE";
|
||||
case RAVA_OP_INPUT_STREAM_SKIP: return "INPUT_STREAM_SKIP";
|
||||
case RAVA_OP_OUTPUT_STREAM_WRITE: return "OUTPUT_STREAM_WRITE";
|
||||
case RAVA_OP_OUTPUT_STREAM_FLUSH: return "OUTPUT_STREAM_FLUSH";
|
||||
case RAVA_OP_STREAM_CLOSE: return "STREAM_CLOSE";
|
||||
case RAVA_OP_INETADDRESS_GET_BY_NAME: return "INETADDRESS_GET_BY_NAME";
|
||||
case RAVA_OP_INETADDRESS_GET_LOCAL_HOST: return "INETADDRESS_GET_LOCAL_HOST";
|
||||
case RAVA_OP_INETADDRESS_GET_LOOPBACK: return "INETADDRESS_GET_LOOPBACK";
|
||||
case RAVA_OP_INETADDRESS_GET_HOST_NAME: return "INETADDRESS_GET_HOST_NAME";
|
||||
case RAVA_OP_INETADDRESS_GET_HOST_ADDRESS: return "INETADDRESS_GET_HOST_ADDRESS";
|
||||
case RAVA_OP_INETADDRESS_IS_LOOPBACK: return "INETADDRESS_IS_LOOPBACK";
|
||||
case RAVA_OP_INETADDRESS_IS_ANY_LOCAL: return "INETADDRESS_IS_ANY_LOCAL";
|
||||
case RAVA_OP_INETADDRESS_GET_ALL_BY_NAME: return "INETADDRESS_GET_ALL_BY_NAME";
|
||||
case RAVA_OP_INETADDRESS_GET_ADDRESS: return "INETADDRESS_GET_ADDRESS";
|
||||
case RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS: return "INETADDRESS_IS_MULTICAST_ADDRESS";
|
||||
case RAVA_OP_INETADDRESS_IS_REACHABLE: return "INETADDRESS_IS_REACHABLE";
|
||||
case RAVA_OP_SOCKET_GET_PORT: return "SOCKET_GET_PORT";
|
||||
case RAVA_OP_SOCKET_GET_LOCAL_PORT: return "SOCKET_GET_LOCAL_PORT";
|
||||
case RAVA_OP_SOCKET_GET_INET_ADDRESS: return "SOCKET_GET_INET_ADDRESS";
|
||||
case RAVA_OP_SOCKET_GET_LOCAL_ADDRESS: return "SOCKET_GET_LOCAL_ADDRESS";
|
||||
case RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT: return "SERVER_SOCKET_GET_LOCAL_PORT";
|
||||
case RAVA_OP_SERVER_SOCKET_IS_BOUND: return "SERVER_SOCKET_IS_BOUND";
|
||||
case RAVA_OP_SERVER_SOCKET_IS_CLOSED: return "SERVER_SOCKET_IS_CLOSED";
|
||||
case RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE: return "SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE";
|
||||
case RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE: return "SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE";
|
||||
case RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS: return "SERVER_SOCKET_SET_REUSE_ADDRESS";
|
||||
case RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS: return "SERVER_SOCKET_GET_REUSE_ADDRESS";
|
||||
case RAVA_OP_SOCKET_SET_SO_TIMEOUT: return "SOCKET_SET_SO_TIMEOUT";
|
||||
case RAVA_OP_SOCKET_GET_SO_TIMEOUT: return "SOCKET_GET_SO_TIMEOUT";
|
||||
case RAVA_OP_SOCKET_SET_TCP_NODELAY: return "SOCKET_SET_TCP_NODELAY";
|
||||
case RAVA_OP_SOCKET_GET_TCP_NODELAY: return "SOCKET_GET_TCP_NODELAY";
|
||||
case RAVA_OP_SOCKET_BIND: return "SOCKET_BIND";
|
||||
case RAVA_OP_SOCKET_IS_CONNECTED: return "SOCKET_IS_CONNECTED";
|
||||
case RAVA_OP_SOCKET_SHUTDOWN_INPUT: return "SOCKET_SHUTDOWN_INPUT";
|
||||
case RAVA_OP_SOCKET_SHUTDOWN_OUTPUT: return "SOCKET_SHUTDOWN_OUTPUT";
|
||||
case RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN: return "SOCKET_IS_INPUT_SHUTDOWN";
|
||||
case RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN: return "SOCKET_IS_OUTPUT_SHUTDOWN";
|
||||
case RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE: return "SOCKET_SET_SEND_BUFFER_SIZE";
|
||||
case RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE: return "SOCKET_GET_SEND_BUFFER_SIZE";
|
||||
case RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE: return "SOCKET_SET_RECEIVE_BUFFER_SIZE";
|
||||
case RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE: return "SOCKET_GET_RECEIVE_BUFFER_SIZE";
|
||||
case RAVA_OP_SOCKET_SET_KEEP_ALIVE: return "SOCKET_SET_KEEP_ALIVE";
|
||||
case RAVA_OP_SOCKET_GET_KEEP_ALIVE: return "SOCKET_GET_KEEP_ALIVE";
|
||||
case RAVA_OP_SOCKET_SET_REUSE_ADDRESS: return "SOCKET_SET_REUSE_ADDRESS";
|
||||
case RAVA_OP_SOCKET_GET_REUSE_ADDRESS: return "SOCKET_GET_REUSE_ADDRESS";
|
||||
case RAVA_OP_METHOD_REF: return "METHOD_REF";
|
||||
case RAVA_OP_METHOD_REF_INVOKE: return "METHOD_REF_INVOKE";
|
||||
default: return "UNKNOWN";
|
||||
|
||||
50
ir/ir.h
50
ir/ir.h
@ -156,59 +156,9 @@ typedef enum {
|
||||
RAVA_OP_SOCKET_GET_INPUT_STREAM,
|
||||
RAVA_OP_SOCKET_GET_OUTPUT_STREAM,
|
||||
RAVA_OP_INPUT_STREAM_READ,
|
||||
RAVA_OP_INPUT_STREAM_READ_BYTES,
|
||||
RAVA_OP_INPUT_STREAM_AVAILABLE,
|
||||
RAVA_OP_INPUT_STREAM_SKIP,
|
||||
RAVA_OP_OUTPUT_STREAM_WRITE,
|
||||
RAVA_OP_OUTPUT_STREAM_FLUSH,
|
||||
RAVA_OP_STREAM_CLOSE,
|
||||
|
||||
RAVA_OP_INETADDRESS_GET_BY_NAME,
|
||||
RAVA_OP_INETADDRESS_GET_LOCAL_HOST,
|
||||
RAVA_OP_INETADDRESS_GET_LOOPBACK,
|
||||
RAVA_OP_INETADDRESS_GET_HOST_NAME,
|
||||
RAVA_OP_INETADDRESS_GET_HOST_ADDRESS,
|
||||
RAVA_OP_INETADDRESS_IS_LOOPBACK,
|
||||
RAVA_OP_INETADDRESS_IS_ANY_LOCAL,
|
||||
RAVA_OP_INETADDRESS_GET_ALL_BY_NAME,
|
||||
RAVA_OP_INETADDRESS_GET_ADDRESS,
|
||||
RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS,
|
||||
RAVA_OP_INETADDRESS_IS_REACHABLE,
|
||||
|
||||
RAVA_OP_SOCKET_GET_PORT,
|
||||
RAVA_OP_SOCKET_GET_LOCAL_PORT,
|
||||
RAVA_OP_SOCKET_GET_INET_ADDRESS,
|
||||
RAVA_OP_SOCKET_GET_LOCAL_ADDRESS,
|
||||
RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT,
|
||||
RAVA_OP_SERVER_SOCKET_IS_BOUND,
|
||||
RAVA_OP_SERVER_SOCKET_IS_CLOSED,
|
||||
RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE,
|
||||
RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE,
|
||||
RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS,
|
||||
RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS,
|
||||
|
||||
RAVA_OP_SOCKET_SET_SO_TIMEOUT,
|
||||
RAVA_OP_SOCKET_GET_SO_TIMEOUT,
|
||||
RAVA_OP_SOCKET_SET_TCP_NODELAY,
|
||||
RAVA_OP_SOCKET_GET_TCP_NODELAY,
|
||||
|
||||
RAVA_OP_SOCKET_BIND,
|
||||
RAVA_OP_SOCKET_IS_CONNECTED,
|
||||
RAVA_OP_SOCKET_SHUTDOWN_INPUT,
|
||||
RAVA_OP_SOCKET_SHUTDOWN_OUTPUT,
|
||||
RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN,
|
||||
RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN,
|
||||
|
||||
RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE,
|
||||
RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE,
|
||||
RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE,
|
||||
RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE,
|
||||
|
||||
RAVA_OP_SOCKET_SET_KEEP_ALIVE,
|
||||
RAVA_OP_SOCKET_GET_KEEP_ALIVE,
|
||||
RAVA_OP_SOCKET_SET_REUSE_ADDRESS,
|
||||
RAVA_OP_SOCKET_GET_REUSE_ADDRESS,
|
||||
|
||||
RAVA_OP_METHOD_REF,
|
||||
RAVA_OP_METHOD_REF_INVOKE
|
||||
} RavaOpCode_e;
|
||||
|
||||
366
ir/ir_gen.c
366
ir/ir_gen.c
@ -513,52 +513,7 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
bool is_socket_get_output_stream = false;
|
||||
bool is_server_socket_accept = false;
|
||||
bool is_input_stream_read = false;
|
||||
bool is_input_stream_read_bytes = false;
|
||||
bool is_input_stream_available = false;
|
||||
bool is_input_stream_skip = false;
|
||||
bool is_output_stream_write = false;
|
||||
bool is_output_stream_flush = false;
|
||||
bool is_inetaddress_get_by_name = false;
|
||||
bool is_inetaddress_get_local_host = false;
|
||||
bool is_inetaddress_get_loopback = false;
|
||||
bool is_inetaddress_get_host_name = false;
|
||||
bool is_inetaddress_get_host_address = false;
|
||||
bool is_inetaddress_is_loopback = false;
|
||||
bool is_inetaddress_is_any_local = false;
|
||||
bool is_inetaddress_get_all_by_name = false;
|
||||
bool is_inetaddress_get_address = false;
|
||||
bool is_inetaddress_is_multicast_address = false;
|
||||
bool is_inetaddress_is_reachable = false;
|
||||
bool is_socket_get_port = false;
|
||||
bool is_socket_get_local_port = false;
|
||||
bool is_socket_get_inet_address = false;
|
||||
bool is_socket_get_local_address = false;
|
||||
bool is_server_socket_get_local_port = false;
|
||||
bool is_server_socket_is_bound = false;
|
||||
bool is_server_socket_is_closed = false;
|
||||
bool is_server_socket_set_receive_buffer_size = false;
|
||||
bool is_server_socket_get_receive_buffer_size = false;
|
||||
bool is_server_socket_set_reuse_address = false;
|
||||
bool is_server_socket_get_reuse_address = false;
|
||||
bool is_socket_set_so_timeout = false;
|
||||
bool is_socket_get_so_timeout = false;
|
||||
bool is_socket_set_tcp_nodelay = false;
|
||||
bool is_socket_get_tcp_nodelay = false;
|
||||
bool is_socket_bind = false;
|
||||
bool is_socket_is_connected = false;
|
||||
bool is_socket_shutdown_input = false;
|
||||
bool is_socket_shutdown_output = false;
|
||||
bool is_socket_is_input_shutdown = false;
|
||||
bool is_socket_is_output_shutdown = false;
|
||||
bool is_socket_set_send_buffer_size = false;
|
||||
bool is_socket_get_send_buffer_size = false;
|
||||
bool is_socket_set_receive_buffer_size = false;
|
||||
bool is_socket_get_receive_buffer_size = false;
|
||||
bool is_socket_set_keep_alive = false;
|
||||
bool is_socket_get_keep_alive = false;
|
||||
bool is_socket_set_reuse_address = false;
|
||||
bool is_socket_get_reuse_address = false;
|
||||
RavaASTNode_t *inetaddress_object = NULL;
|
||||
RavaASTNode_t *string_object = NULL;
|
||||
RavaASTNode_t *collection_object = NULL;
|
||||
RavaASTNode_t *socket_object = NULL;
|
||||
@ -630,19 +585,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
is_math_random = true;
|
||||
}
|
||||
}
|
||||
if (member->data.member_access.object->type == RAVA_AST_IDENTIFIER_EXPR &&
|
||||
strcmp(member->data.member_access.object->data.identifier.name, "InetAddress") == 0) {
|
||||
const char *method = member->data.member_access.member;
|
||||
if (strcmp(method, "getByName") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_inetaddress_get_by_name = true;
|
||||
} else if (strcmp(method, "getLocalHost") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_get_local_host = true;
|
||||
} else if (strcmp(method, "getLoopbackAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_get_loopback = true;
|
||||
} else if (strcmp(method, "getAllByName") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_inetaddress_get_all_by_name = true;
|
||||
}
|
||||
}
|
||||
if (strcmp(member->data.member_access.member, "length") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_string_length = true;
|
||||
string_object = member->data.member_access.object;
|
||||
@ -718,132 +660,15 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
} else if (strcmp(member->data.member_access.member, "accept") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_server_socket_accept = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "read") == 0 && expr->data.call.arguments_count == 0) {
|
||||
} else if (strcmp(member->data.member_access.member, "read") == 0) {
|
||||
is_input_stream_read = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "read") == 0 && expr->data.call.arguments_count == 3) {
|
||||
is_input_stream_read_bytes = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "available") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_input_stream_available = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "skip") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_input_stream_skip = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "write") == 0) {
|
||||
is_output_stream_write = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "flush") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_output_stream_flush = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "close") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_close = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getHostName") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_get_host_name = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getHostAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_get_host_address = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isLoopbackAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_is_loopback = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isAnyLocalAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_is_any_local = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_get_address = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isMulticastAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_inetaddress_is_multicast_address = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isReachable") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_inetaddress_is_reachable = true;
|
||||
inetaddress_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getPort") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_port = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getLocalPort") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_local_port = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getInetAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_inet_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getLocalAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_local_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isBound") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_server_socket_is_bound = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isClosed") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_server_socket_is_closed = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setReceiveBufferSize") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_server_socket_set_receive_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getReceiveBufferSize") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_server_socket_get_receive_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setReuseAddress") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_server_socket_set_reuse_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getReuseAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_server_socket_get_reuse_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setSoTimeout") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_so_timeout = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getSoTimeout") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_so_timeout = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setTcpNoDelay") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_tcp_nodelay = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getTcpNoDelay") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_tcp_nodelay = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "bind") == 0 && expr->data.call.arguments_count == 2) {
|
||||
is_socket_bind = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isConnected") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_is_connected = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "shutdownInput") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_shutdown_input = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "shutdownOutput") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_shutdown_output = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isInputShutdown") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_is_input_shutdown = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isOutputShutdown") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_is_output_shutdown = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setSendBufferSize") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_send_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getSendBufferSize") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_send_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setReceiveBufferSize") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_receive_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getReceiveBufferSize") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_receive_buffer_size = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setKeepAlive") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_keep_alive = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getKeepAlive") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_keep_alive = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "setReuseAddress") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_socket_set_reuse_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "getReuseAddress") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_socket_get_reuse_address = true;
|
||||
socket_object = member->data.member_access.object;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1051,22 +876,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_INPUT_STREAM_READ;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_input_stream_read_bytes) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
|
||||
}
|
||||
instr.opcode = RAVA_OP_INPUT_STREAM_READ_BYTES;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_input_stream_available) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_INPUT_STREAM_AVAILABLE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_input_stream_skip) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_INPUT_STREAM_SKIP;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_output_stream_write) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
|
||||
@ -1075,183 +884,10 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
instr.opcode = RAVA_OP_OUTPUT_STREAM_WRITE;
|
||||
instr.operand.int_value = expr->data.call.arguments_count;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_output_stream_flush) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_OUTPUT_STREAM_FLUSH;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_close) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_CLOSE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_by_name) {
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_BY_NAME;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_local_host) {
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_LOCAL_HOST;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_loopback) {
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_LOOPBACK;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_host_name) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_HOST_NAME;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_host_address) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_HOST_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_is_loopback) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_IS_LOOPBACK;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_is_any_local) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_IS_ANY_LOCAL;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_all_by_name) {
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_ALL_BY_NAME;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_get_address) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_GET_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_is_multicast_address) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_inetaddress_is_reachable) {
|
||||
_rava_ir_gen_expression(gen, inetaddress_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_INETADDRESS_IS_REACHABLE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_port) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_PORT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_local_port) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_LOCAL_PORT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_inet_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_INET_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_local_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_LOCAL_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_get_local_port) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_is_bound) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_IS_BOUND;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_is_closed) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_IS_CLOSED;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_set_receive_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_get_receive_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_set_reuse_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_server_socket_get_reuse_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_so_timeout) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_SO_TIMEOUT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_so_timeout) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_SO_TIMEOUT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_tcp_nodelay) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_TCP_NODELAY;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_tcp_nodelay) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_TCP_NODELAY;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_bind) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[1]);
|
||||
instr.opcode = RAVA_OP_SOCKET_BIND;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_is_connected) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_IS_CONNECTED;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_shutdown_input) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_SHUTDOWN_INPUT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_shutdown_output) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_SHUTDOWN_OUTPUT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_is_input_shutdown) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_is_output_shutdown) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_send_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_send_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_receive_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_receive_buffer_size) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_keep_alive) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_KEEP_ALIVE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_keep_alive) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_KEEP_ALIVE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_set_reuse_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_SOCKET_SET_REUSE_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_socket_get_reuse_address) {
|
||||
_rava_ir_gen_expression(gen, socket_object);
|
||||
instr.opcode = RAVA_OP_SOCKET_GET_REUSE_ADDRESS;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_println || is_print) {
|
||||
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
|
||||
|
||||
1501
runtime/runtime.c
1501
runtime/runtime.c
File diff suppressed because it is too large
Load Diff
@ -32,8 +32,7 @@ typedef enum {
|
||||
RAVA_VAL_HASHMAP,
|
||||
RAVA_VAL_SOCKET,
|
||||
RAVA_VAL_STREAM,
|
||||
RAVA_VAL_METHOD_REF,
|
||||
RAVA_VAL_INETADDRESS
|
||||
RAVA_VAL_METHOD_REF
|
||||
} RavaValueType_e;
|
||||
|
||||
typedef struct {
|
||||
@ -50,7 +49,6 @@ typedef struct RavaHashMap_t RavaHashMap_t;
|
||||
typedef struct RavaSocket_t RavaSocket_t;
|
||||
typedef struct RavaStream_t RavaStream_t;
|
||||
typedef struct RavaMethodRef_t RavaMethodRef_t;
|
||||
typedef struct RavaInetAddress_t RavaInetAddress_t;
|
||||
|
||||
#define RAVA_OBJECT_HASH_SIZE 32
|
||||
|
||||
@ -81,7 +79,6 @@ struct RavaValue_t {
|
||||
RavaSocket_t *socket_val;
|
||||
RavaStream_t *stream_val;
|
||||
RavaMethodRef_t *method_ref_val;
|
||||
RavaInetAddress_t *inetaddress_val;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -121,9 +118,6 @@ struct RavaSocket_t {
|
||||
int fd;
|
||||
bool connected;
|
||||
bool closed;
|
||||
bool bound;
|
||||
bool input_shutdown;
|
||||
bool output_shutdown;
|
||||
};
|
||||
|
||||
#define RAVA_STREAM_TYPE_INPUT 1
|
||||
@ -146,17 +140,6 @@ struct RavaMethodRef_t {
|
||||
bool has_target;
|
||||
};
|
||||
|
||||
#define RAVA_INETADDRESS_IPV4 1
|
||||
#define RAVA_INETADDRESS_IPV6 2
|
||||
|
||||
struct RavaInetAddress_t {
|
||||
RavaGCHeader_t gc;
|
||||
int address_type;
|
||||
uint8_t address[16];
|
||||
char *hostname;
|
||||
char *hostaddress;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
RavaValue_t *values;
|
||||
size_t capacity;
|
||||
@ -382,63 +365,6 @@ int rava_stream_read_byte(RavaStream_t *stream);
|
||||
void rava_stream_write(RavaStream_t *stream, const char *data);
|
||||
void rava_stream_write_byte(RavaStream_t *stream, int byte);
|
||||
void rava_stream_close(RavaStream_t *stream);
|
||||
int rava_stream_read_bytes(RavaStream_t *stream, RavaArray_t *arr, int off, int len);
|
||||
int rava_stream_available(RavaStream_t *stream);
|
||||
void rava_stream_flush(RavaStream_t *stream);
|
||||
long rava_stream_skip(RavaStream_t *stream, long n);
|
||||
|
||||
RavaInetAddress_t* rava_inetaddress_create(void);
|
||||
RavaInetAddress_t* rava_inetaddress_get_by_name(const char *host);
|
||||
RavaInetAddress_t* rava_inetaddress_get_local_host(void);
|
||||
RavaInetAddress_t* rava_inetaddress_get_loopback(void);
|
||||
char* rava_inetaddress_get_host_name(RavaInetAddress_t *addr);
|
||||
char* rava_inetaddress_get_host_address(RavaInetAddress_t *addr);
|
||||
bool rava_inetaddress_is_loopback(RavaInetAddress_t *addr);
|
||||
bool rava_inetaddress_is_any_local(RavaInetAddress_t *addr);
|
||||
RavaArray_t* rava_inetaddress_get_all_by_name(const char *host);
|
||||
RavaArray_t* rava_inetaddress_get_address(RavaInetAddress_t *addr);
|
||||
bool rava_inetaddress_is_multicast_address(RavaInetAddress_t *addr);
|
||||
bool rava_inetaddress_is_reachable(RavaInetAddress_t *addr, int timeout);
|
||||
int rava_socket_get_port(RavaSocket_t *socket);
|
||||
int rava_socket_get_local_port(RavaSocket_t *socket);
|
||||
RavaInetAddress_t* rava_socket_get_inet_address(RavaSocket_t *socket);
|
||||
RavaInetAddress_t* rava_socket_get_local_address(RavaSocket_t *socket);
|
||||
int rava_server_socket_get_local_port(RavaSocket_t *socket);
|
||||
bool rava_server_socket_is_bound(RavaSocket_t *socket);
|
||||
bool rava_server_socket_is_closed(RavaSocket_t *socket);
|
||||
void rava_server_socket_set_so_timeout(RavaSocket_t *socket, int timeout);
|
||||
int rava_server_socket_get_so_timeout(RavaSocket_t *socket);
|
||||
void rava_server_socket_set_receive_buffer_size(RavaSocket_t *socket, int size);
|
||||
int rava_server_socket_get_receive_buffer_size(RavaSocket_t *socket);
|
||||
void rava_server_socket_set_reuse_address(RavaSocket_t *socket, bool reuse);
|
||||
bool rava_server_socket_get_reuse_address(RavaSocket_t *socket);
|
||||
void rava_socket_set_so_timeout(RavaSocket_t *socket, int timeout_ms);
|
||||
int rava_socket_get_so_timeout(RavaSocket_t *socket);
|
||||
void rava_socket_set_tcp_nodelay(RavaSocket_t *socket, bool nodelay);
|
||||
bool rava_socket_get_tcp_nodelay(RavaSocket_t *socket);
|
||||
void rava_socket_bind(RavaSocket_t *socket, const char *host, int port);
|
||||
bool rava_socket_is_connected(RavaSocket_t *socket);
|
||||
bool rava_socket_is_closed(RavaSocket_t *socket);
|
||||
bool rava_socket_is_bound(RavaSocket_t *socket);
|
||||
void rava_socket_shutdown_input(RavaSocket_t *socket);
|
||||
void rava_socket_shutdown_output(RavaSocket_t *socket);
|
||||
bool rava_socket_is_input_shutdown(RavaSocket_t *socket);
|
||||
bool rava_socket_is_output_shutdown(RavaSocket_t *socket);
|
||||
void rava_socket_set_send_buffer_size(RavaSocket_t *socket, int size);
|
||||
int rava_socket_get_send_buffer_size(RavaSocket_t *socket);
|
||||
void rava_socket_set_receive_buffer_size(RavaSocket_t *socket, int size);
|
||||
int rava_socket_get_receive_buffer_size(RavaSocket_t *socket);
|
||||
void rava_socket_set_keep_alive(RavaSocket_t *socket, bool keepalive);
|
||||
bool rava_socket_get_keep_alive(RavaSocket_t *socket);
|
||||
void rava_socket_set_reuse_address(RavaSocket_t *socket, bool reuse);
|
||||
bool rava_socket_get_reuse_address(RavaSocket_t *socket);
|
||||
|
||||
static inline RavaValue_t rava_value_inetaddress(RavaInetAddress_t *addr) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_INETADDRESS;
|
||||
val.data.inetaddress_val = addr;
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline RavaValue_t rava_value_socket(RavaSocket_t *socket) {
|
||||
RavaValue_t val;
|
||||
@ -511,7 +437,6 @@ RavaValue_t rava_native_to_value(RavaNativeValue_t native);
|
||||
#define RAVA_GC_TYPE_SOCKET 6
|
||||
#define RAVA_GC_TYPE_STREAM 7
|
||||
#define RAVA_GC_TYPE_METHODREF 8
|
||||
#define RAVA_GC_TYPE_INETADDRESS 9
|
||||
|
||||
void rava_gc_init(void);
|
||||
void rava_gc_shutdown(void);
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
RavaExceptionStack_t* rava_exception_stack_create(void) {
|
||||
RavaExceptionStack_t *stack = calloc(1, sizeof(RavaExceptionStack_t));
|
||||
if (!stack) return NULL;
|
||||
stack->count = 0;
|
||||
return stack;
|
||||
}
|
||||
|
||||
void rava_exception_stack_destroy(RavaExceptionStack_t *stack) {
|
||||
free(stack);
|
||||
}
|
||||
|
||||
void rava_exception_stack_push(RavaExceptionStack_t *stack, RavaExceptionHandler_t handler) {
|
||||
if (stack->count >= RAVA_MAX_EXCEPTION_DEPTH) return;
|
||||
stack->handlers[stack->count++] = handler;
|
||||
}
|
||||
|
||||
bool rava_exception_stack_pop(RavaExceptionStack_t *stack, RavaExceptionHandler_t *handler) {
|
||||
if (stack->count == 0) return false;
|
||||
*handler = stack->handlers[--stack->count];
|
||||
return true;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
const char* _rava_intern_string(RavaVM_t *vm, const char *str) {
|
||||
uint32_t h = _intern_hash(str);
|
||||
for (size_t i = 0; i < RAVA_INTERN_TABLE_SIZE; i++) {
|
||||
size_t idx = (h + i) & (RAVA_INTERN_TABLE_SIZE - 1);
|
||||
if (vm->intern_table.strings[idx] == NULL) {
|
||||
if (vm->intern_table.count >= RAVA_INTERN_TABLE_SIZE - 1) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
fprintf(stderr, "Warning: String intern table full (%d entries)\n",
|
||||
RAVA_INTERN_TABLE_SIZE);
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
vm->intern_table.strings[idx] = strdup(str);
|
||||
vm->intern_table.count++;
|
||||
return vm->intern_table.strings[idx];
|
||||
}
|
||||
if (strcmp(vm->intern_table.strings[idx], str) == 0) {
|
||||
return vm->intern_table.strings[idx];
|
||||
}
|
||||
}
|
||||
return strdup(str);
|
||||
}
|
||||
@ -1,174 +0,0 @@
|
||||
#ifndef RAVA_RUNTIME_INTERNAL_H
|
||||
#define RAVA_RUNTIME_INTERNAL_H
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "runtime.h"
|
||||
#include "labeltable.h"
|
||||
#include "methodcache.h"
|
||||
#include "nanbox.h"
|
||||
#include "fastframe.h"
|
||||
#include "superinst.h"
|
||||
#include "../utils/safe_alloc.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define LIKELY(x) (x)
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define STACK_ENSURE_CAPACITY(stack) do { \
|
||||
if ((stack)->top >= (stack)->capacity) { \
|
||||
(stack)->capacity *= 2; \
|
||||
RavaValue_t *_new_values = realloc((stack)->values, sizeof(RavaValue_t) * (stack)->capacity); \
|
||||
if (_new_values) (stack)->values = _new_values; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define STACK_PUSH(stack, val) do { \
|
||||
STACK_ENSURE_CAPACITY(stack); \
|
||||
(stack)->values[(stack)->top++] = (val); \
|
||||
} while(0)
|
||||
|
||||
#define STACK_POP(stack) ((stack)->top > 0 ? (stack)->values[--(stack)->top] : (RavaValue_t){0})
|
||||
|
||||
#define STACK_PEEK(stack) ((stack)->top > 0 ? (stack)->values[(stack)->top - 1] : (RavaValue_t){0})
|
||||
|
||||
#define STACK_PUSH_INT(stack, v) do { \
|
||||
STACK_ENSURE_CAPACITY(stack); \
|
||||
RavaValue_t _v; _v.type = RAVA_VAL_INT; _v.data.int_val = (v); \
|
||||
(stack)->values[(stack)->top++] = _v; \
|
||||
} while(0)
|
||||
|
||||
#define STACK_PUSH_LONG(stack, v) do { \
|
||||
STACK_ENSURE_CAPACITY(stack); \
|
||||
RavaValue_t _v; _v.type = RAVA_VAL_LONG; _v.data.long_val = (v); \
|
||||
(stack)->values[(stack)->top++] = _v; \
|
||||
} while(0)
|
||||
|
||||
#define STACK_PUSH_BOOL(stack, v) do { \
|
||||
STACK_ENSURE_CAPACITY(stack); \
|
||||
RavaValue_t _v; _v.type = RAVA_VAL_BOOLEAN; _v.data.bool_val = (v); \
|
||||
(stack)->values[(stack)->top++] = _v; \
|
||||
} while(0)
|
||||
|
||||
#define VALUE_IS_INT(v) ((v).type == RAVA_VAL_INT)
|
||||
#define VALUE_IS_LONG(v) ((v).type == RAVA_VAL_LONG)
|
||||
#define VALUE_AS_INT_FAST(v) ((v).data.int_val)
|
||||
#define VALUE_AS_LONG_FAST(v) ((v).data.long_val)
|
||||
|
||||
static inline RavaNanboxValue_t rava_value_to_nanbox(RavaValue_t val) {
|
||||
switch (val.type) {
|
||||
case RAVA_VAL_INT: return rava_nanbox_int(val.data.int_val);
|
||||
case RAVA_VAL_LONG: return rava_nanbox_long(val.data.long_val);
|
||||
case RAVA_VAL_DOUBLE: return rava_nanbox_double(val.data.double_val);
|
||||
case RAVA_VAL_FLOAT: return rava_nanbox_double((double)val.data.float_val);
|
||||
case RAVA_VAL_BOOLEAN: return rava_nanbox_bool(val.data.bool_val);
|
||||
case RAVA_VAL_NULL: return rava_nanbox_null();
|
||||
case RAVA_VAL_STRING: return rava_nanbox_string(val.data.string_val);
|
||||
case RAVA_VAL_OBJECT: return rava_nanbox_object(val.data.object_val);
|
||||
case RAVA_VAL_ARRAY: return rava_nanbox_array(val.data.array_val);
|
||||
default: return rava_nanbox_null();
|
||||
}
|
||||
}
|
||||
|
||||
static inline RavaValue_t rava_nanbox_to_value(RavaNanboxValue_t nb) {
|
||||
RavaValue_t val;
|
||||
if (rava_nanbox_is_int(nb)) {
|
||||
val.type = RAVA_VAL_INT;
|
||||
val.data.int_val = rava_nanbox_as_int(nb);
|
||||
} else if (rava_nanbox_is_long(nb)) {
|
||||
val.type = RAVA_VAL_LONG;
|
||||
val.data.long_val = rava_nanbox_as_long(nb);
|
||||
} else if (rava_nanbox_is_double(nb)) {
|
||||
val.type = RAVA_VAL_DOUBLE;
|
||||
val.data.double_val = rava_nanbox_as_double(nb);
|
||||
} else if (rava_nanbox_is_bool(nb)) {
|
||||
val.type = RAVA_VAL_BOOLEAN;
|
||||
val.data.bool_val = rava_nanbox_as_bool(nb);
|
||||
} else if (rava_nanbox_is_null(nb)) {
|
||||
val.type = RAVA_VAL_NULL;
|
||||
val.data.object_val = NULL;
|
||||
} else if (rava_nanbox_is_string(nb)) {
|
||||
val.type = RAVA_VAL_STRING;
|
||||
val.data.string_val = (char*)rava_nanbox_as_string(nb);
|
||||
} else if (rava_nanbox_is_object(nb)) {
|
||||
val.type = RAVA_VAL_OBJECT;
|
||||
val.data.object_val = rava_nanbox_as_object(nb);
|
||||
} else if (rava_nanbox_is_array(nb)) {
|
||||
val.type = RAVA_VAL_ARRAY;
|
||||
val.data.array_val = rava_nanbox_as_array(nb);
|
||||
} else {
|
||||
val.type = RAVA_VAL_NULL;
|
||||
val.data.object_val = NULL;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_field_hash(const char *name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*name) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_class_hash(const char *name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*name) hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
||||
return hash & (RAVA_CLASS_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_method_hash(const char *name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*name) hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
||||
return hash & (RAVA_METHOD_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_static_hash(const char *class_name, const char *field_name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*class_name) hash = ((hash << 5) + hash) ^ (uint32_t)*class_name++;
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)'.';
|
||||
while (*field_name) hash = ((hash << 5) + hash) ^ (uint32_t)*field_name++;
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline uint32_t _intern_hash(const char *str) {
|
||||
uint32_t hash = 5381;
|
||||
while (*str) hash = ((hash << 5) + hash) ^ (uint32_t)*str++;
|
||||
return hash;
|
||||
}
|
||||
|
||||
char* _rava_get_string_buffer(RavaVM_t *vm, size_t needed);
|
||||
const char* _rava_intern_string(RavaVM_t *vm, const char *str);
|
||||
void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm);
|
||||
|
||||
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name);
|
||||
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name);
|
||||
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name);
|
||||
|
||||
RavaStaticFieldTable_t* rava_static_field_table_create(void);
|
||||
void rava_static_field_table_destroy(RavaStaticFieldTable_t *table);
|
||||
RavaValue_t* rava_static_field_table_get(RavaStaticFieldTable_t *table, const char *class_name, const char *field_name);
|
||||
void rava_static_field_table_set(RavaStaticFieldTable_t *table, const char *class_name, const char *field_name, RavaValue_t value);
|
||||
|
||||
RavaExceptionStack_t* rava_exception_stack_create(void);
|
||||
void rava_exception_stack_destroy(RavaExceptionStack_t *stack);
|
||||
void rava_exception_stack_push(RavaExceptionStack_t *stack, RavaExceptionHandler_t handler);
|
||||
bool rava_exception_stack_pop(RavaExceptionStack_t *stack, RavaExceptionHandler_t *handler);
|
||||
|
||||
bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, RavaInstruction_t *instr);
|
||||
bool _rava_vm_execute_fast(RavaVM_t *vm, RavaCallFrame_t *frame);
|
||||
bool _rava_vm_execute_ultrafast(RavaVM_t *vm, RavaMethod_t *entry_method);
|
||||
bool _rava_vm_run_static_initializers(RavaVM_t *vm);
|
||||
|
||||
extern bool g_gc_initialized;
|
||||
|
||||
#endif
|
||||
@ -1,53 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
bool g_gc_initialized = false;
|
||||
|
||||
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
|
||||
uint32_t h = _rava_class_hash(class_name);
|
||||
int idx = vm->class_hash[h];
|
||||
if (idx >= 0 && (size_t)idx < vm->program->class_count &&
|
||||
strcmp(vm->program->classes[idx]->name, class_name) == 0) {
|
||||
return vm->program->classes[idx];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < vm->program->class_count; i++) {
|
||||
if (strcmp(vm->program->classes[i]->name, class_name) == 0) {
|
||||
vm->class_hash[h] = (int)i;
|
||||
return vm->program->classes[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name) {
|
||||
const char *current_class = class_name;
|
||||
while (current_class) {
|
||||
RavaClass_t *class = _rava_vm_find_class(vm, current_class);
|
||||
if (!class) break;
|
||||
uint32_t h = _rava_method_hash(method_name);
|
||||
int idx = class->method_hash[h];
|
||||
if (idx >= 0 && (size_t)idx < class->method_count &&
|
||||
strcmp(class->methods[idx]->name, method_name) == 0) {
|
||||
return class->methods[idx];
|
||||
}
|
||||
for (size_t j = 0; j < class->method_count; j++) {
|
||||
if (strcmp(class->methods[j]->name, method_name) == 0) {
|
||||
class->method_hash[h] = (int)j;
|
||||
return class->methods[j];
|
||||
}
|
||||
}
|
||||
current_class = class->superclass;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name) {
|
||||
MethodCache_t *cache = (MethodCache_t*)vm->method_cache;
|
||||
RavaMethod_t *cached = rava_methodcache_lookup(cache, class_name, method_name);
|
||||
if (cached) return cached;
|
||||
RavaMethod_t *method = _rava_vm_find_method(vm, class_name, method_name);
|
||||
if (method) {
|
||||
rava_methodcache_insert(cache, class_name, method_name, method);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
@ -178,8 +178,6 @@ int32_t rava_object_hashcode(RavaValue_t value) {
|
||||
return (int32_t)((uintptr_t)value.data.socket_val >> 3);
|
||||
case RAVA_VAL_STREAM:
|
||||
return (int32_t)((uintptr_t)value.data.stream_val >> 3);
|
||||
case RAVA_VAL_INETADDRESS:
|
||||
return (int32_t)((uintptr_t)value.data.inetaddress_val >> 3);
|
||||
case RAVA_VAL_METHOD_REF:
|
||||
return (int32_t)((uintptr_t)value.data.method_ref_val >> 3);
|
||||
}
|
||||
@ -289,13 +287,6 @@ char* rava_object_tostring(RavaValue_t value) {
|
||||
snprintf(buffer, 128, "Stream@%x",
|
||||
(unsigned int)((uintptr_t)value.data.stream_val >> 3));
|
||||
break;
|
||||
case RAVA_VAL_INETADDRESS:
|
||||
if (value.data.inetaddress_val && value.data.inetaddress_val->hostaddress) {
|
||||
snprintf(buffer, 128, "/%s", value.data.inetaddress_val->hostaddress);
|
||||
} else {
|
||||
strcpy(buffer, "/null");
|
||||
}
|
||||
break;
|
||||
case RAVA_VAL_METHOD_REF:
|
||||
if (value.data.method_ref_val) {
|
||||
snprintf(buffer, 128, "%s::%s",
|
||||
@ -342,8 +333,6 @@ const char* rava_object_getclass(RavaValue_t value) {
|
||||
return "Socket";
|
||||
case RAVA_VAL_STREAM:
|
||||
return "Stream";
|
||||
case RAVA_VAL_INETADDRESS:
|
||||
return "InetAddress";
|
||||
case RAVA_VAL_METHOD_REF:
|
||||
return "MethodReference";
|
||||
}
|
||||
|
||||
@ -9,14 +9,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
RavaSocket_t* rava_socket_create(void) {
|
||||
RavaSocket_t *sock = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET);
|
||||
@ -70,8 +62,6 @@ RavaSocket_t* rava_server_socket_create(int port) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
sock->bound = true;
|
||||
|
||||
if (listen(sock->fd, 10) < 0) {
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
@ -214,607 +204,3 @@ void rava_stream_close(RavaStream_t *stream) {
|
||||
if (!stream) return;
|
||||
stream->closed = true;
|
||||
}
|
||||
|
||||
int rava_stream_read_bytes(RavaStream_t *stream, RavaArray_t *arr, int off, int len) {
|
||||
if (!stream || stream->closed || stream->fd < 0) return -1;
|
||||
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return -1;
|
||||
if (!arr || off < 0 || len <= 0) return -1;
|
||||
if ((size_t)(off + len) > arr->length) return -1;
|
||||
|
||||
char *buffer = malloc(len);
|
||||
if (!buffer) return -1;
|
||||
|
||||
ssize_t bytes_read = read(stream->fd, buffer, len);
|
||||
if (bytes_read <= 0) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < bytes_read; i++) {
|
||||
rava_array_set_value(arr, off + i, rava_value_int((unsigned char)buffer[i]));
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return (int)bytes_read;
|
||||
}
|
||||
|
||||
int rava_stream_available(RavaStream_t *stream) {
|
||||
if (!stream || stream->closed || stream->fd < 0) return 0;
|
||||
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return 0;
|
||||
|
||||
int available = 0;
|
||||
if (ioctl(stream->fd, FIONREAD, &available) < 0) {
|
||||
return 0;
|
||||
}
|
||||
return available;
|
||||
}
|
||||
|
||||
void rava_stream_flush(RavaStream_t *stream) {
|
||||
if (!stream || stream->closed || stream->fd < 0) return;
|
||||
if (stream->stream_type != RAVA_STREAM_TYPE_OUTPUT) return;
|
||||
fsync(stream->fd);
|
||||
}
|
||||
|
||||
long rava_stream_skip(RavaStream_t *stream, long n) {
|
||||
if (!stream || stream->closed || stream->fd < 0) return 0;
|
||||
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return 0;
|
||||
if (n <= 0) return 0;
|
||||
|
||||
long skipped = 0;
|
||||
char buffer[1024];
|
||||
while (skipped < n) {
|
||||
long to_read = (n - skipped > 1024) ? 1024 : (n - skipped);
|
||||
ssize_t read_count = read(stream->fd, buffer, (size_t)to_read);
|
||||
if (read_count <= 0) break;
|
||||
skipped += read_count;
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_inetaddress_create(void) {
|
||||
RavaInetAddress_t *addr = rava_gc_alloc(sizeof(RavaInetAddress_t), RAVA_GC_TYPE_INETADDRESS);
|
||||
if (!addr) return NULL;
|
||||
memset((char*)addr + sizeof(RavaGCHeader_t), 0, sizeof(RavaInetAddress_t) - sizeof(RavaGCHeader_t));
|
||||
addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
return addr;
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_inetaddress_get_by_name(const char *host) {
|
||||
if (!host) return NULL;
|
||||
|
||||
struct addrinfo hints, *res;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
int status = getaddrinfo(host, NULL, &hints, &res);
|
||||
if (status != 0) return NULL;
|
||||
|
||||
RavaInetAddress_t *addr = rava_inetaddress_create();
|
||||
if (!addr) {
|
||||
freeaddrinfo(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr->hostname = strdup(host);
|
||||
|
||||
if (res->ai_family == AF_INET) {
|
||||
addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in*)res->ai_addr;
|
||||
memcpy(addr->address, &ipv4->sin_addr, 4);
|
||||
char ip[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, ip, sizeof(ip));
|
||||
addr->hostaddress = strdup(ip);
|
||||
} else if (res->ai_family == AF_INET6) {
|
||||
addr->address_type = RAVA_INETADDRESS_IPV6;
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)res->ai_addr;
|
||||
memcpy(addr->address, &ipv6->sin6_addr, 16);
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, ip, sizeof(ip));
|
||||
addr->hostaddress = strdup(ip);
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return addr;
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_inetaddress_get_local_host(void) {
|
||||
char hostname[256];
|
||||
if (gethostname(hostname, sizeof(hostname)) != 0) {
|
||||
return rava_inetaddress_get_loopback();
|
||||
}
|
||||
RavaInetAddress_t *addr = rava_inetaddress_get_by_name(hostname);
|
||||
if (!addr) {
|
||||
return rava_inetaddress_get_loopback();
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_inetaddress_get_loopback(void) {
|
||||
RavaInetAddress_t *addr = rava_inetaddress_create();
|
||||
if (!addr) return NULL;
|
||||
|
||||
addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
addr->address[0] = 127;
|
||||
addr->address[1] = 0;
|
||||
addr->address[2] = 0;
|
||||
addr->address[3] = 1;
|
||||
addr->hostname = strdup("localhost");
|
||||
addr->hostaddress = strdup("127.0.0.1");
|
||||
return addr;
|
||||
}
|
||||
|
||||
char* rava_inetaddress_get_host_name(RavaInetAddress_t *addr) {
|
||||
if (!addr) return NULL;
|
||||
if (addr->hostname) return addr->hostname;
|
||||
|
||||
char host[NI_MAXHOST];
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
memcpy(&sa.sin_addr, addr->address, 4);
|
||||
|
||||
int result = getnameinfo((struct sockaddr*)&sa, sizeof(sa), host, sizeof(host), NULL, 0, 0);
|
||||
if (result == 0) {
|
||||
addr->hostname = strdup(host);
|
||||
return addr->hostname;
|
||||
}
|
||||
return addr->hostaddress;
|
||||
}
|
||||
|
||||
char* rava_inetaddress_get_host_address(RavaInetAddress_t *addr) {
|
||||
if (!addr) return NULL;
|
||||
if (addr->hostaddress) return addr->hostaddress;
|
||||
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
|
||||
inet_ntop(AF_INET, addr->address, ip, sizeof(ip));
|
||||
} else {
|
||||
inet_ntop(AF_INET6, addr->address, ip, sizeof(ip));
|
||||
}
|
||||
addr->hostaddress = strdup(ip);
|
||||
return addr->hostaddress;
|
||||
}
|
||||
|
||||
bool rava_inetaddress_is_loopback(RavaInetAddress_t *addr) {
|
||||
if (!addr) return false;
|
||||
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
|
||||
return addr->address[0] == 127;
|
||||
}
|
||||
static const uint8_t ipv6_loopback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
|
||||
return memcmp(addr->address, ipv6_loopback, 16) == 0;
|
||||
}
|
||||
|
||||
bool rava_inetaddress_is_any_local(RavaInetAddress_t *addr) {
|
||||
if (!addr) return false;
|
||||
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
|
||||
return addr->address[0] == 0 && addr->address[1] == 0 &&
|
||||
addr->address[2] == 0 && addr->address[3] == 0;
|
||||
}
|
||||
static const uint8_t ipv6_any[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
return memcmp(addr->address, ipv6_any, 16) == 0;
|
||||
}
|
||||
|
||||
RavaArray_t* rava_inetaddress_get_all_by_name(const char *host) {
|
||||
if (!host) return NULL;
|
||||
|
||||
struct addrinfo hints, *res, *p;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (getaddrinfo(host, NULL, &hints, &res) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
for (p = res; p != NULL; p = p->ai_next) {
|
||||
count++;
|
||||
}
|
||||
|
||||
RavaArray_t *array = rava_gc_alloc(sizeof(RavaArray_t), RAVA_GC_TYPE_ARRAY);
|
||||
if (!array) {
|
||||
freeaddrinfo(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array->length = count;
|
||||
array->element_type = RAVA_VAL_INETADDRESS;
|
||||
array->data = calloc(count, sizeof(RavaValue_t));
|
||||
if (!array->data && count > 0) {
|
||||
freeaddrinfo(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RavaValue_t *values = (RavaValue_t *)array->data;
|
||||
size_t i = 0;
|
||||
for (p = res; p != NULL; p = p->ai_next) {
|
||||
RavaInetAddress_t *addr = rava_inetaddress_create();
|
||||
if (addr) {
|
||||
if (p->ai_family == AF_INET) {
|
||||
addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
|
||||
memcpy(addr->address, &ipv4->sin_addr, 4);
|
||||
} else if (p->ai_family == AF_INET6) {
|
||||
addr->address_type = RAVA_INETADDRESS_IPV6;
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
|
||||
memcpy(addr->address, &ipv6->sin6_addr, 16);
|
||||
}
|
||||
addr->hostname = host ? strdup(host) : NULL;
|
||||
values[i] = rava_value_inetaddress(addr);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return array;
|
||||
}
|
||||
|
||||
RavaArray_t* rava_inetaddress_get_address(RavaInetAddress_t *addr) {
|
||||
if (!addr) return NULL;
|
||||
|
||||
size_t len = (addr->address_type == RAVA_INETADDRESS_IPV4) ? 4 : 16;
|
||||
RavaArray_t *array = rava_gc_alloc(sizeof(RavaArray_t), RAVA_GC_TYPE_ARRAY);
|
||||
if (!array) return NULL;
|
||||
|
||||
array->length = len;
|
||||
array->element_type = RAVA_VAL_INT;
|
||||
array->data = calloc(len, sizeof(int64_t));
|
||||
if (!array->data && len > 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int64_t *values = (int64_t *)array->data;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
values[i] = addr->address[i];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
bool rava_inetaddress_is_multicast_address(RavaInetAddress_t *addr) {
|
||||
if (!addr) return false;
|
||||
|
||||
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
|
||||
return (addr->address[0] >= 224 && addr->address[0] <= 239);
|
||||
} else {
|
||||
return addr->address[0] == 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
bool rava_inetaddress_is_reachable(RavaInetAddress_t *addr, int timeout) {
|
||||
if (!addr) return false;
|
||||
|
||||
int sock = socket(addr->address_type == RAVA_INETADDRESS_IPV4 ? AF_INET : AF_INET6, SOCK_STREAM, 0);
|
||||
if (sock < 0) return false;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
|
||||
bool result = false;
|
||||
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(7);
|
||||
memcpy(&sa.sin_addr, addr->address, 4);
|
||||
|
||||
int res = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
|
||||
if (res == 0 || (res < 0 && errno == EINPROGRESS)) {
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(sock, &fdset);
|
||||
struct timeval tv2;
|
||||
tv2.tv_sec = timeout / 1000;
|
||||
tv2.tv_usec = (timeout % 1000) * 1000;
|
||||
if (select(sock + 1, NULL, &fdset, NULL, &tv2) > 0) {
|
||||
int so_error;
|
||||
socklen_t len = sizeof(so_error);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
|
||||
result = (so_error == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int rava_socket_get_port(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return -1;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
if (getpeername(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return ntohs(addr.sin_port);
|
||||
}
|
||||
|
||||
int rava_socket_get_local_port(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return -1;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
if (getsockname(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return ntohs(addr.sin_port);
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_socket_get_inet_address(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return NULL;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
if (getpeername(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RavaInetAddress_t *inet_addr = rava_inetaddress_create();
|
||||
if (!inet_addr) return NULL;
|
||||
|
||||
inet_addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
memcpy(inet_addr->address, &addr.sin_addr, 4);
|
||||
|
||||
char ip[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
|
||||
inet_addr->hostaddress = strdup(ip);
|
||||
|
||||
return inet_addr;
|
||||
}
|
||||
|
||||
RavaInetAddress_t* rava_socket_get_local_address(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return NULL;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
if (getsockname(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RavaInetAddress_t *inet_addr = rava_inetaddress_create();
|
||||
if (!inet_addr) return NULL;
|
||||
|
||||
inet_addr->address_type = RAVA_INETADDRESS_IPV4;
|
||||
memcpy(inet_addr->address, &addr.sin_addr, 4);
|
||||
|
||||
char ip[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
|
||||
inet_addr->hostaddress = strdup(ip);
|
||||
|
||||
return inet_addr;
|
||||
}
|
||||
|
||||
int rava_server_socket_get_local_port(RavaSocket_t *socket) {
|
||||
return rava_socket_get_local_port(socket);
|
||||
}
|
||||
|
||||
bool rava_server_socket_is_bound(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return false;
|
||||
return socket->bound;
|
||||
}
|
||||
|
||||
bool rava_server_socket_is_closed(RavaSocket_t *socket) {
|
||||
if (!socket) return true;
|
||||
return socket->closed;
|
||||
}
|
||||
|
||||
void rava_server_socket_set_so_timeout(RavaSocket_t *socket, int timeout) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
int rava_server_socket_get_so_timeout(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return 0;
|
||||
struct timeval tv;
|
||||
socklen_t len = sizeof(tv);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
|
||||
return 0;
|
||||
}
|
||||
return (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void rava_server_socket_set_receive_buffer_size(RavaSocket_t *socket, int size) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
|
||||
}
|
||||
|
||||
int rava_server_socket_get_receive_buffer_size(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return 0;
|
||||
int size = 0;
|
||||
socklen_t len = sizeof(size);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, &len) == 0) {
|
||||
return size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rava_server_socket_set_reuse_address(RavaSocket_t *socket, bool reuse) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
int val = reuse ? 1 : 0;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||
}
|
||||
|
||||
bool rava_server_socket_get_reuse_address(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return false;
|
||||
int val = 0;
|
||||
socklen_t len = sizeof(val);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, &len) == 0) {
|
||||
return val != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void rava_socket_set_so_timeout(RavaSocket_t *socket, int timeout_ms) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
int rava_socket_get_so_timeout(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return 0;
|
||||
|
||||
struct timeval tv;
|
||||
socklen_t len = sizeof(tv);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
|
||||
return 0;
|
||||
}
|
||||
return (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void rava_socket_set_tcp_nodelay(RavaSocket_t *socket, bool nodelay) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
|
||||
int flag = nodelay ? 1 : 0;
|
||||
setsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||
}
|
||||
|
||||
bool rava_socket_get_tcp_nodelay(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return false;
|
||||
|
||||
int flag = 0;
|
||||
socklen_t len = sizeof(flag);
|
||||
if (getsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &flag, &len) < 0) {
|
||||
return false;
|
||||
}
|
||||
return flag != 0;
|
||||
}
|
||||
|
||||
void rava_socket_bind(RavaSocket_t *socket, const char *host, int port) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
if (socket->bound) return;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
if (host && strcmp(host, "0.0.0.0") != 0) {
|
||||
if (inet_pton(AF_INET, host, &addr.sin_addr) <= 0) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
if (bind(socket->fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
||||
socket->bound = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool rava_socket_is_connected(RavaSocket_t *socket) {
|
||||
if (!socket) return false;
|
||||
return socket->connected && !socket->closed;
|
||||
}
|
||||
|
||||
bool rava_socket_is_closed(RavaSocket_t *socket) {
|
||||
if (!socket) return true;
|
||||
return socket->closed;
|
||||
}
|
||||
|
||||
bool rava_socket_is_bound(RavaSocket_t *socket) {
|
||||
if (!socket) return false;
|
||||
return socket->bound;
|
||||
}
|
||||
|
||||
void rava_socket_shutdown_input(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
if (socket->input_shutdown) return;
|
||||
|
||||
shutdown(socket->fd, SHUT_RD);
|
||||
socket->input_shutdown = true;
|
||||
}
|
||||
|
||||
void rava_socket_shutdown_output(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
if (socket->output_shutdown) return;
|
||||
|
||||
shutdown(socket->fd, SHUT_WR);
|
||||
socket->output_shutdown = true;
|
||||
}
|
||||
|
||||
bool rava_socket_is_input_shutdown(RavaSocket_t *socket) {
|
||||
if (!socket) return false;
|
||||
return socket->input_shutdown;
|
||||
}
|
||||
|
||||
bool rava_socket_is_output_shutdown(RavaSocket_t *socket) {
|
||||
if (!socket) return false;
|
||||
return socket->output_shutdown;
|
||||
}
|
||||
|
||||
void rava_socket_set_send_buffer_size(RavaSocket_t *socket, int size) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
|
||||
}
|
||||
|
||||
int rava_socket_get_send_buffer_size(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return 0;
|
||||
int size = 0;
|
||||
socklen_t len = sizeof(size);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_SNDBUF, &size, &len) == 0) {
|
||||
return size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rava_socket_set_receive_buffer_size(RavaSocket_t *socket, int size) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
|
||||
}
|
||||
|
||||
int rava_socket_get_receive_buffer_size(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return 0;
|
||||
int size = 0;
|
||||
socklen_t len = sizeof(size);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, &len) == 0) {
|
||||
return size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rava_socket_set_keep_alive(RavaSocket_t *socket, bool keepalive) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
int val = keepalive ? 1 : 0;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
|
||||
}
|
||||
|
||||
bool rava_socket_get_keep_alive(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return false;
|
||||
int val = 0;
|
||||
socklen_t len = sizeof(val);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_KEEPALIVE, &val, &len) == 0) {
|
||||
return val != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void rava_socket_set_reuse_address(RavaSocket_t *socket, bool reuse) {
|
||||
if (!socket || socket->fd < 0) return;
|
||||
int val = reuse ? 1 : 0;
|
||||
setsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||
}
|
||||
|
||||
bool rava_socket_get_reuse_address(RavaSocket_t *socket) {
|
||||
if (!socket || socket->fd < 0) return false;
|
||||
int val = 0;
|
||||
socklen_t len = sizeof(val);
|
||||
if (getsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, &len) == 0) {
|
||||
return val != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,127 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
RavaStack_t* rava_stack_create(size_t capacity) {
|
||||
RavaStack_t *stack = malloc(sizeof(RavaStack_t));
|
||||
if (!stack) return NULL;
|
||||
stack->capacity = capacity;
|
||||
stack->values = malloc(sizeof(RavaValue_t) * capacity);
|
||||
if (!stack->values) {
|
||||
free(stack);
|
||||
return NULL;
|
||||
}
|
||||
stack->top = 0;
|
||||
return stack;
|
||||
}
|
||||
|
||||
void rava_stack_destroy(RavaStack_t *stack) {
|
||||
if (!stack) return;
|
||||
free(stack->values);
|
||||
free(stack);
|
||||
}
|
||||
|
||||
void rava_stack_push(RavaStack_t *stack, RavaValue_t value) {
|
||||
if (stack->top >= stack->capacity) {
|
||||
stack->capacity *= 2;
|
||||
RavaValue_t *new_values = rava_safe_realloc(stack->values, sizeof(RavaValue_t) * stack->capacity);
|
||||
if (!new_values) return;
|
||||
stack->values = new_values;
|
||||
}
|
||||
stack->values[stack->top++] = value;
|
||||
}
|
||||
|
||||
RavaValue_t rava_stack_pop(RavaStack_t *stack) {
|
||||
if (stack->top == 0) {
|
||||
return rava_value_int(0);
|
||||
}
|
||||
return stack->values[--stack->top];
|
||||
}
|
||||
|
||||
RavaValue_t rava_stack_peek(RavaStack_t *stack) {
|
||||
if (stack->top == 0) {
|
||||
return rava_value_int(0);
|
||||
}
|
||||
return stack->values[stack->top - 1];
|
||||
}
|
||||
|
||||
bool rava_stack_is_empty(RavaStack_t *stack) {
|
||||
return stack->top == 0;
|
||||
}
|
||||
|
||||
RavaCallFrame_t* rava_call_frame_create(RavaMethod_t *method) {
|
||||
RavaCallFrame_t *frame = calloc(1, sizeof(RavaCallFrame_t));
|
||||
if (!frame) return NULL;
|
||||
frame->method = method;
|
||||
frame->local_count = method->local_count;
|
||||
frame->locals = calloc(method->local_count, sizeof(RavaValue_t));
|
||||
if (!frame->locals && method->local_count > 0) {
|
||||
free(frame);
|
||||
return NULL;
|
||||
}
|
||||
frame->pc = 0;
|
||||
size_t stack_size = method->max_stack > 0 ? (size_t)method->max_stack : 64;
|
||||
frame->operand_stack = rava_stack_create(stack_size);
|
||||
if (!frame->operand_stack) {
|
||||
free(frame->locals);
|
||||
free(frame);
|
||||
return NULL;
|
||||
}
|
||||
frame->has_this = false;
|
||||
frame->this_ref = rava_value_null();
|
||||
return frame;
|
||||
}
|
||||
|
||||
void rava_call_frame_destroy(RavaCallFrame_t *frame) {
|
||||
if (!frame) return;
|
||||
free(frame->locals);
|
||||
rava_stack_destroy(frame->operand_stack);
|
||||
free(frame);
|
||||
}
|
||||
|
||||
RavaCallStack_t* rava_call_stack_create(void) {
|
||||
RavaCallStack_t *stack = malloc(sizeof(RavaCallStack_t));
|
||||
if (!stack) return NULL;
|
||||
stack->capacity = 256;
|
||||
stack->frames = malloc(sizeof(RavaCallFrame_t*) * stack->capacity);
|
||||
if (!stack->frames) {
|
||||
free(stack);
|
||||
return NULL;
|
||||
}
|
||||
stack->count = 0;
|
||||
return stack;
|
||||
}
|
||||
|
||||
void rava_call_stack_destroy(RavaCallStack_t *stack) {
|
||||
if (!stack) return;
|
||||
for (size_t i = 0; i < stack->count; i++) {
|
||||
rava_call_frame_destroy(stack->frames[i]);
|
||||
}
|
||||
free(stack->frames);
|
||||
free(stack);
|
||||
}
|
||||
|
||||
#define RAVA_MAX_CALL_STACK_DEPTH 10000
|
||||
|
||||
bool rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame) {
|
||||
if (stack->count >= RAVA_MAX_CALL_STACK_DEPTH) {
|
||||
return false;
|
||||
}
|
||||
if (stack->count >= stack->capacity) {
|
||||
stack->capacity *= 2;
|
||||
RavaCallFrame_t **new_frames = rava_safe_realloc(stack->frames, sizeof(RavaCallFrame_t*) * stack->capacity);
|
||||
if (!new_frames) return false;
|
||||
stack->frames = new_frames;
|
||||
}
|
||||
stack->frames[stack->count++] = frame;
|
||||
return true;
|
||||
}
|
||||
|
||||
RavaCallFrame_t* rava_call_stack_pop(RavaCallStack_t *stack) {
|
||||
if (stack->count == 0) return NULL;
|
||||
RavaCallFrame_t *frame = stack->frames[--stack->count];
|
||||
return frame;
|
||||
}
|
||||
|
||||
RavaCallFrame_t* rava_call_stack_current(RavaCallStack_t *stack) {
|
||||
if (stack->count == 0) return NULL;
|
||||
return stack->frames[stack->count - 1];
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
RavaStaticFieldTable_t* rava_static_field_table_create(void) {
|
||||
RavaStaticFieldTable_t *table = malloc(sizeof(RavaStaticFieldTable_t));
|
||||
if (!table) return NULL;
|
||||
table->capacity = 16;
|
||||
table->fields = calloc(table->capacity, sizeof(RavaStaticField_t));
|
||||
if (!table->fields) {
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
table->count = 0;
|
||||
for (int i = 0; i < RAVA_STATIC_HASH_SIZE; i++) {
|
||||
table->hash_table[i] = -1;
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
void rava_static_field_table_destroy(RavaStaticFieldTable_t *table) {
|
||||
if (!table) return;
|
||||
for (size_t i = 0; i < table->count; i++) {
|
||||
free(table->fields[i].class_name);
|
||||
free(table->fields[i].field_name);
|
||||
}
|
||||
free(table->fields);
|
||||
free(table);
|
||||
}
|
||||
|
||||
RavaValue_t* rava_static_field_table_get(RavaStaticFieldTable_t *table,
|
||||
const char *class_name,
|
||||
const char *field_name) {
|
||||
uint32_t hash = _rava_static_hash(class_name, field_name);
|
||||
|
||||
for (size_t probe = 0; probe < RAVA_STATIC_HASH_SIZE; probe++) {
|
||||
uint32_t slot = (hash + probe) & (RAVA_STATIC_HASH_SIZE - 1);
|
||||
int idx = table->hash_table[slot];
|
||||
|
||||
if (idx == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size_t)idx < table->count &&
|
||||
strcmp(table->fields[idx].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[idx].field_name, field_name) == 0) {
|
||||
return &table->fields[idx].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rava_static_field_table_set(RavaStaticFieldTable_t *table,
|
||||
const char *class_name,
|
||||
const char *field_name,
|
||||
RavaValue_t value) {
|
||||
uint32_t hash = _rava_static_hash(class_name, field_name);
|
||||
|
||||
for (size_t probe = 0; probe < RAVA_STATIC_HASH_SIZE; probe++) {
|
||||
uint32_t slot = (hash + probe) & (RAVA_STATIC_HASH_SIZE - 1);
|
||||
int idx = table->hash_table[slot];
|
||||
|
||||
if (idx == -1) {
|
||||
if (table->count >= table->capacity) {
|
||||
size_t new_cap = table->capacity * 2;
|
||||
RavaStaticField_t *new_fields = rava_safe_realloc(table->fields, sizeof(RavaStaticField_t) * new_cap);
|
||||
if (!new_fields) return;
|
||||
table->fields = new_fields;
|
||||
table->capacity = new_cap;
|
||||
}
|
||||
|
||||
table->fields[table->count].class_name = strdup(class_name);
|
||||
table->fields[table->count].field_name = strdup(field_name);
|
||||
table->fields[table->count].value = value;
|
||||
table->hash_table[slot] = (int)table->count;
|
||||
table->count++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)idx < table->count &&
|
||||
strcmp(table->fields[idx].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[idx].field_name, field_name) == 0) {
|
||||
table->fields[idx].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
#include "runtime_internal.h"
|
||||
|
||||
RavaValue_t rava_value_string(const char *str) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_STRING;
|
||||
val.data.string_val = str ? strdup(str) : NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
const char* rava_value_as_string(RavaValue_t value) {
|
||||
if (value.type == RAVA_VAL_STRING) {
|
||||
return value.data.string_val ? value.data.string_val : "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
char* _rava_get_string_buffer(RavaVM_t *vm, size_t needed) {
|
||||
if (needed >= RAVA_STRING_BUFFER_SIZE) {
|
||||
return malloc(needed);
|
||||
}
|
||||
char *buf = vm->string_pool.buffers[vm->string_pool.current];
|
||||
vm->string_pool.current = (vm->string_pool.current + 1) % RAVA_STRING_BUFFER_COUNT;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm) {
|
||||
if (!obj || !name) return;
|
||||
|
||||
uint32_t hash = _rava_field_hash(name);
|
||||
|
||||
for (size_t probe = 0; probe < RAVA_OBJECT_HASH_SIZE; probe++) {
|
||||
uint32_t idx = (hash + probe) & (RAVA_OBJECT_HASH_SIZE - 1);
|
||||
int field_idx = obj->field_hash[idx];
|
||||
|
||||
if (field_idx == -1) {
|
||||
if (obj->field_count >= obj->field_capacity) {
|
||||
size_t new_cap = obj->field_capacity * 2;
|
||||
char **new_names = rava_safe_realloc(obj->field_names, new_cap * sizeof(char*));
|
||||
RavaValue_t *new_values = rava_safe_realloc(obj->field_values, new_cap * sizeof(RavaValue_t));
|
||||
if (!new_names || !new_values) return;
|
||||
obj->field_names = new_names;
|
||||
obj->field_values = new_values;
|
||||
obj->field_capacity = new_cap;
|
||||
}
|
||||
obj->field_names[obj->field_count] = (char*)(vm ? _rava_intern_string(vm, name) : strdup(name));
|
||||
obj->field_values[obj->field_count] = value;
|
||||
obj->field_hash[idx] = (int)obj->field_count;
|
||||
obj->field_count++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)field_idx < obj->field_count &&
|
||||
strcmp(obj->field_names[field_idx], name) == 0) {
|
||||
obj->field_values[field_idx] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t rava_value_as_int(RavaValue_t value) {
|
||||
switch (value.type) {
|
||||
case RAVA_VAL_INT: return value.data.int_val;
|
||||
case RAVA_VAL_LONG: return value.data.long_val;
|
||||
case RAVA_VAL_FLOAT: return (int64_t)value.data.float_val;
|
||||
case RAVA_VAL_DOUBLE: return (int64_t)value.data.double_val;
|
||||
case RAVA_VAL_BOOLEAN: return value.data.bool_val ? 1 : 0;
|
||||
case RAVA_VAL_CHAR: return value.data.char_val;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t rava_value_as_long(RavaValue_t value) {
|
||||
switch (value.type) {
|
||||
case RAVA_VAL_INT: return value.data.int_val;
|
||||
case RAVA_VAL_LONG: return value.data.long_val;
|
||||
case RAVA_VAL_FLOAT: return (int64_t)value.data.float_val;
|
||||
case RAVA_VAL_DOUBLE: return (int64_t)value.data.double_val;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double rava_value_as_double(RavaValue_t value) {
|
||||
switch (value.type) {
|
||||
case RAVA_VAL_INT: return value.data.int_val;
|
||||
case RAVA_VAL_LONG: return (double)value.data.long_val;
|
||||
case RAVA_VAL_FLOAT: return value.data.float_val;
|
||||
case RAVA_VAL_DOUBLE: return value.data.double_val;
|
||||
default: return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
bool rava_value_as_boolean(RavaValue_t value) {
|
||||
if (value.type == RAVA_VAL_BOOLEAN) {
|
||||
return value.data.bool_val;
|
||||
}
|
||||
return rava_value_as_int(value) != 0;
|
||||
}
|
||||
@ -270,9 +270,6 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
|
||||
if (strcmp(name, "Math") == 0) {
|
||||
return rava_type_from_name("Math");
|
||||
}
|
||||
if (strcmp(name, "InetAddress") == 0) {
|
||||
return rava_type_from_name("InetAddress");
|
||||
}
|
||||
|
||||
RavaSymbol_t *symbol = rava_symbol_table_resolve(analyzer->symbol_table, name);
|
||||
if (!symbol) {
|
||||
@ -331,14 +328,6 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
|
||||
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
|
||||
_rava_semantic_check_expression(analyzer, expr->data.call.arguments[i]);
|
||||
}
|
||||
if (expr->data.call.callee->type == RAVA_AST_IDENTIFIER_EXPR) {
|
||||
const char *func_name = expr->data.call.callee->data.identifier.name;
|
||||
if (strcmp(func_name, "readLine") == 0) {
|
||||
return rava_type_create_class("String");
|
||||
} else if (strcmp(func_name, "sendResponse") == 0 || strcmp(func_name, "handleRequest") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_VOID);
|
||||
}
|
||||
}
|
||||
if (expr->data.call.callee->type == RAVA_AST_MEMBER_ACCESS_EXPR) {
|
||||
RavaASTNode_t *member = expr->data.call.callee;
|
||||
const char *method = member->data.member_access.member;
|
||||
@ -371,60 +360,13 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
|
||||
return rava_type_create_primitive(RAVA_TYPE_DOUBLE);
|
||||
}
|
||||
}
|
||||
if (member->data.member_access.object->type == RAVA_AST_IDENTIFIER_EXPR &&
|
||||
strcmp(member->data.member_access.object->data.identifier.name, "InetAddress") == 0) {
|
||||
if (strcmp(method, "getByName") == 0 || strcmp(method, "getLocalHost") == 0 ||
|
||||
strcmp(method, "getLoopbackAddress") == 0) {
|
||||
return rava_type_create_class("InetAddress");
|
||||
}
|
||||
}
|
||||
if (strcmp(method, "getHostName") == 0 || strcmp(method, "getHostAddress") == 0) {
|
||||
return rava_type_create_class("String");
|
||||
}
|
||||
if (strcmp(method, "isLoopbackAddress") == 0 || strcmp(method, "isAnyLocalAddress") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
|
||||
}
|
||||
if (strcmp(method, "getLocalPort") == 0 || strcmp(method, "getPort") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
}
|
||||
if (strcmp(method, "isBound") == 0 || strcmp(method, "isClosed") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
|
||||
}
|
||||
if (strcmp(method, "getInetAddress") == 0 || strcmp(method, "getLocalAddress") == 0) {
|
||||
return rava_type_create_class("InetAddress");
|
||||
}
|
||||
if (strcmp(method, "accept") == 0) {
|
||||
return rava_type_create_class("Socket");
|
||||
}
|
||||
if (strcmp(method, "getInputStream") == 0) {
|
||||
return rava_type_create_class("InputStream");
|
||||
}
|
||||
if (strcmp(method, "getOutputStream") == 0) {
|
||||
return rava_type_create_class("OutputStream");
|
||||
}
|
||||
if (strcmp(method, "getSoTimeout") == 0 || strcmp(method, "getReceiveBufferSize") == 0 ||
|
||||
strcmp(method, "getSendBufferSize") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
}
|
||||
if (strcmp(method, "getTcpNoDelay") == 0 || strcmp(method, "getKeepAlive") == 0 ||
|
||||
strcmp(method, "getReuseAddress") == 0 || strcmp(method, "isConnected") == 0 ||
|
||||
strcmp(method, "isMulticastAddress") == 0 || strcmp(method, "isReachable") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
|
||||
}
|
||||
if (strcmp(method, "read") == 0 || strcmp(method, "skip") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
}
|
||||
if (strcmp(method, "length") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
} else if (strcmp(method, "charAt") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_CHAR);
|
||||
} else if (strcmp(method, "substring") == 0 || strcmp(method, "toLowerCase") == 0 ||
|
||||
strcmp(method, "toUpperCase") == 0 || strcmp(method, "trim") == 0) {
|
||||
return rava_type_create_class("String");
|
||||
} else if (strcmp(method, "equals") == 0 || strcmp(method, "contains") == 0 ||
|
||||
strcmp(method, "startsWith") == 0 || strcmp(method, "endsWith") == 0) {
|
||||
} else if (strcmp(method, "equals") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
|
||||
} else if (strcmp(method, "compareTo") == 0 || strcmp(method, "indexOf") == 0) {
|
||||
} else if (strcmp(method, "compareTo") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
} else if (strcmp(method, "size") == 0) {
|
||||
return rava_type_create_primitive(RAVA_TYPE_INT);
|
||||
|
||||
BIN
tests/test_array_init.o
Normal file
BIN
tests/test_array_init.o
Normal file
Binary file not shown.
BIN
tests/test_arrays.o
Normal file
BIN
tests/test_arrays.o
Normal file
Binary file not shown.
BIN
tests/test_bitwise.o
Normal file
BIN
tests/test_bitwise.o
Normal file
Binary file not shown.
BIN
tests/test_collections.o
Normal file
BIN
tests/test_collections.o
Normal file
Binary file not shown.
BIN
tests/test_dowhile.o
Normal file
BIN
tests/test_dowhile.o
Normal file
Binary file not shown.
BIN
tests/test_enhanced_for.o
Normal file
BIN
tests/test_enhanced_for.o
Normal file
Binary file not shown.
BIN
tests/test_enums.o
Normal file
BIN
tests/test_enums.o
Normal file
Binary file not shown.
BIN
tests/test_exceptions.o
Normal file
BIN
tests/test_exceptions.o
Normal file
Binary file not shown.
BIN
tests/test_fileio.o
Normal file
BIN
tests/test_fileio.o
Normal file
Binary file not shown.
BIN
tests/test_instance_methods.o
Normal file
BIN
tests/test_instance_methods.o
Normal file
Binary file not shown.
BIN
tests/test_instanceof.o
Normal file
BIN
tests/test_instanceof.o
Normal file
Binary file not shown.
BIN
tests/test_interfaces.o
Normal file
BIN
tests/test_interfaces.o
Normal file
Binary file not shown.
BIN
tests/test_ir.o
Normal file
BIN
tests/test_ir.o
Normal file
Binary file not shown.
BIN
tests/test_lexer.o
Normal file
BIN
tests/test_lexer.o
Normal file
Binary file not shown.
BIN
tests/test_math.o
Normal file
BIN
tests/test_math.o
Normal file
Binary file not shown.
BIN
tests/test_multidim_arrays.o
Normal file
BIN
tests/test_multidim_arrays.o
Normal file
Binary file not shown.
BIN
tests/test_negative.o
Normal file
BIN
tests/test_negative.o
Normal file
Binary file not shown.
BIN
tests/test_objects.o
Normal file
BIN
tests/test_objects.o
Normal file
Binary file not shown.
BIN
tests/test_parser.o
Normal file
BIN
tests/test_parser.o
Normal file
Binary file not shown.
BIN
tests/test_runtime.o
Normal file
BIN
tests/test_runtime.o
Normal file
Binary file not shown.
BIN
tests/test_semantic.o
Normal file
BIN
tests/test_semantic.o
Normal file
Binary file not shown.
BIN
tests/test_shortcircuit.o
Normal file
BIN
tests/test_shortcircuit.o
Normal file
Binary file not shown.
@ -34,320 +34,6 @@ UnittestTestResult_t* test_socket_create_multiple(void) {
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_loopback(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_loopback");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
|
||||
" System.out.println(addr.getHostAddress());\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Loopback address should have IP address");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_localhost(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_localhost");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getLocalHost();\n"
|
||||
" System.out.println(addr.getHostAddress());\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Local host should have an IP address");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_getbyname(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_getbyname");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getByName(\"localhost\");\n"
|
||||
" System.out.println(addr.getHostAddress());\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "localhost should resolve to IP");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_server_socket_local_port(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_server_socket_local_port");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(9995);\n"
|
||||
" int port = server.getLocalPort();\n"
|
||||
" server.close();\n"
|
||||
" return port;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 9995, "ServerSocket should report correct local port");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_bind(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_bind");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" Socket sock = new Socket();\n"
|
||||
" sock.bind(\"127.0.0.1\", 9994);\n"
|
||||
" int result = sock.isBound() ? 1 : 0;\n"
|
||||
" sock.close();\n"
|
||||
" return result;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket should be bound after bind()");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_is_connected(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_connected");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(9993);\n"
|
||||
" Socket client = new Socket();\n"
|
||||
" int before = client.isConnected() ? 1 : 0;\n"
|
||||
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
|
||||
" client.connect(addr, 9993);\n"
|
||||
" int after = client.isConnected() ? 1 : 0;\n"
|
||||
" client.close();\n"
|
||||
" server.close();\n"
|
||||
" return before * 10 + after;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket should report connected state");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_is_closed(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_closed");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" Socket sock = new Socket();\n"
|
||||
" int before = sock.isClosed() ? 1 : 0;\n"
|
||||
" sock.close();\n"
|
||||
" int after = sock.isClosed() ? 1 : 0;\n"
|
||||
" return before * 10 + after;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket should report closed state");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_shutdown_input(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_shutdown_input");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(9992);\n"
|
||||
" Socket client = new Socket();\n"
|
||||
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
|
||||
" client.connect(addr, 9992);\n"
|
||||
" int before = client.isInputShutdown() ? 1 : 0;\n"
|
||||
" client.shutdownInput();\n"
|
||||
" int after = client.isInputShutdown() ? 1 : 0;\n"
|
||||
" client.close();\n"
|
||||
" server.close();\n"
|
||||
" return before * 10 + after;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket should report input shutdown state");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_shutdown_output(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_shutdown_output");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(9991);\n"
|
||||
" Socket client = new Socket();\n"
|
||||
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
|
||||
" client.connect(addr, 9991);\n"
|
||||
" int before = client.isOutputShutdown() ? 1 : 0;\n"
|
||||
" client.shutdownOutput();\n"
|
||||
" int after = client.isOutputShutdown() ? 1 : 0;\n"
|
||||
" client.close();\n"
|
||||
" server.close();\n"
|
||||
" return before * 10 + after;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket should report output shutdown state");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_is_bound(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_bound");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(9990);\n"
|
||||
" int result = server.isBound() ? 1 : 0;\n"
|
||||
" server.close();\n"
|
||||
" return result;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "ServerSocket should be bound after creation");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_buffer_sizes(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_buffer_sizes");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" Socket sock = new Socket();\n"
|
||||
" sock.setSendBufferSize(16384);\n"
|
||||
" sock.setReceiveBufferSize(16384);\n"
|
||||
" int sendSize = sock.getSendBufferSize();\n"
|
||||
" int recvSize = sock.getReceiveBufferSize();\n"
|
||||
" sock.close();\n"
|
||||
" return (sendSize > 0 && recvSize > 0) ? 1 : 0;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket buffer sizes should be retrievable");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_socket_keep_alive_reuse_address(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_keep_alive_reuse_address");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" Socket sock = new Socket();\n"
|
||||
" sock.setKeepAlive(true);\n"
|
||||
" int keepAlive = sock.getKeepAlive() ? 1 : 0;\n"
|
||||
" sock.setKeepAlive(false);\n"
|
||||
" int keepAlive2 = sock.getKeepAlive() ? 1 : 0;\n"
|
||||
" sock.setReuseAddress(true);\n"
|
||||
" int reuse = sock.getReuseAddress() ? 1 : 0;\n"
|
||||
" sock.setReuseAddress(false);\n"
|
||||
" int reuse2 = sock.getReuseAddress() ? 1 : 0;\n"
|
||||
" sock.close();\n"
|
||||
" return (keepAlive == 1 && keepAlive2 == 0 && reuse == 1 && reuse2 == 0) ? 1 : 0;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "Socket KeepAlive and ReuseAddress options should work");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_get_address(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_get_address");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
|
||||
" addr.getAddress();\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "InetAddress.getAddress() should execute");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_is_multicast(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_is_multicast");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
|
||||
" int multicast = addr.isMulticastAddress() ? 1 : 0;\n"
|
||||
" return (multicast == 0) ? 1 : 0;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "InetAddress.isMulticastAddress() should return false for loopback");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_is_reachable(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_is_reachable");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
|
||||
" int reachable = addr.isReachable(1000) ? 1 : 0;\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "InetAddress.isReachable() should execute without error");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_inetaddress_get_all_by_name(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_get_all_by_name");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" InetAddress.getAllByName(\"localhost\");\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "InetAddress.getAllByName() should execute");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
UnittestTestResult_t* test_server_socket_options(void) {
|
||||
UNITTEST_BEGIN_TEST("TestSockets", "test_server_socket_options");
|
||||
|
||||
RAVA_TEST_RUN(_unittest_result,
|
||||
"public class Test {\n"
|
||||
" public static int main() {\n"
|
||||
" ServerSocket server = new ServerSocket(0);\n"
|
||||
" server.setReceiveBufferSize(16384);\n"
|
||||
" int bufSize = server.getReceiveBufferSize();\n"
|
||||
" server.setReuseAddress(true);\n"
|
||||
" int reuse = server.getReuseAddress() ? 1 : 0;\n"
|
||||
" server.setReuseAddress(false);\n"
|
||||
" int reuse2 = server.getReuseAddress() ? 1 : 0;\n"
|
||||
" return (bufSize > 0 && reuse == 1 && reuse2 == 0) ? 1 : 0;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"Test", "main", 1, "ServerSocket buffer and reuse address options should work");
|
||||
|
||||
UNITTEST_END_TEST();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
UnittestConfig_t *config = unittest_config_create();
|
||||
config->verbosity = 2;
|
||||
@ -362,23 +48,6 @@ int main(int argc, char **argv) {
|
||||
UnittestTestCase_t *tc = unittest_test_case_create("TestSockets");
|
||||
unittest_test_case_add_result(tc, test_socket_create_server());
|
||||
unittest_test_case_add_result(tc, test_socket_create_multiple());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_loopback());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_localhost());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_getbyname());
|
||||
unittest_test_case_add_result(tc, test_server_socket_local_port());
|
||||
unittest_test_case_add_result(tc, test_socket_bind());
|
||||
unittest_test_case_add_result(tc, test_socket_is_connected());
|
||||
unittest_test_case_add_result(tc, test_socket_is_closed());
|
||||
unittest_test_case_add_result(tc, test_socket_shutdown_input());
|
||||
unittest_test_case_add_result(tc, test_socket_shutdown_output());
|
||||
unittest_test_case_add_result(tc, test_socket_is_bound());
|
||||
unittest_test_case_add_result(tc, test_socket_buffer_sizes());
|
||||
unittest_test_case_add_result(tc, test_socket_keep_alive_reuse_address());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_get_address());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_is_multicast());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_is_reachable());
|
||||
unittest_test_case_add_result(tc, test_inetaddress_get_all_by_name());
|
||||
unittest_test_case_add_result(tc, test_server_socket_options());
|
||||
unittest_test_suite_add_test_case(suite, tc);
|
||||
|
||||
unittest_generate_report(suite, config);
|
||||
|
||||
BIN
tests/test_static.o
Normal file
BIN
tests/test_static.o
Normal file
Binary file not shown.
BIN
tests/test_static_init.o
Normal file
BIN
tests/test_static_init.o
Normal file
Binary file not shown.
BIN
tests/test_string_methods.o
Normal file
BIN
tests/test_string_methods.o
Normal file
Binary file not shown.
BIN
tests/test_strings.o
Normal file
BIN
tests/test_strings.o
Normal file
Binary file not shown.
BIN
tests/test_switch.o
Normal file
BIN
tests/test_switch.o
Normal file
Binary file not shown.
BIN
tests/test_ternary.o
Normal file
BIN
tests/test_ternary.o
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user