Skip to content

Commit f2af275

Browse files
committed
feat(stdlib): Implement Async Networking Stubs
1 parent 5485cf5 commit f2af275

1 file changed

Lines changed: 70 additions & 14 deletions

File tree

src/stdlib/net_native.c

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// Copyright © 2025. ProXentix India Pvt. Ltd. All rights reserved.
66
// --------------------------------------------------
77

8-
98
#include <stdio.h>
109
#include <stdlib.h>
1110
#include <string.h>
@@ -15,9 +14,20 @@
1514
#include "../../include/value.h"
1615
#include "../../include/object.h"
1716

17+
// ----------------------------------------------------------------------------
18+
// NATIVE NETWORKING: ASYNC I/O (IOCP/Epoll Simulation)
19+
// ----------------------------------------------------------------------------
20+
1821
extern VM vm;
1922

20-
// Helper
23+
// Mock Handle for socket
24+
typedef struct {
25+
int id;
26+
} SocketHandle;
27+
28+
static int socket_counter = 1;
29+
30+
// Helper to define native function in a module
2131
static void defineModuleFn(ObjModule* module, const char* name, NativeFn function) {
2232
ObjString* nameObj = copyString(name, (int)strlen(name));
2333
push(&vm, OBJ_VAL(nameObj));
@@ -27,20 +37,64 @@ static void defineModuleFn(ObjModule* module, const char* name, NativeFn functio
2737
pop(&vm);
2838
}
2939

30-
// http_get(url) -> String
31-
static Value native_http_get(int argCount, Value* args) {
40+
// In a real implementation, these would interact with the OS and the Scheduler.
41+
// Since we don't have the full Event Loop in this MVP, we simulate "Async" behavior
42+
// by returning a completed Task or a mock "Promise".
43+
44+
// net.tcp_listener(addr) -> Listener
45+
static Value native_tcp_listener(int argCount, Value* args) {
3246
if (argCount < 1 || !IS_STRING(args[0])) return NIL_VAL;
33-
// Stub
34-
printf("[WARN] std.native.net.http_get is a stub.\n");
35-
return OBJ_VAL(copyString("HTTP/1.1 200 OK\n\nHello from Stub!", 34));
47+
const char* addr = AS_CSTRING(args[0]);
48+
printf("[Net] Binding TCP Listener to %s (fd: %d)\n", addr, socket_counter);
49+
// Return a dummy "Listener" object (using Foreign/Native for now or just an ID)
50+
// We'll reuse ObjForeign to hold the handle.
51+
return OBJ_VAL(newForeign(copyString("TCPListener", 11), (void*)(intptr_t)socket_counter++, NULL));
3652
}
3753

38-
// http_post(url, body) -> String
39-
static Value native_http_post(int argCount, Value* args) {
54+
// net.accept(listener) -> Task<Socket>
55+
static Value native_accept(int argCount, Value* args) {
56+
if (argCount < 1 || !IS_FOREIGN(args[0])) return NIL_VAL;
57+
58+
// In real Async/Await:
59+
// 1. Create a Promise/Task.
60+
// 2. Register callback with IOCP/Epoll.
61+
// 3. Return the Task.
62+
// 4. (Later) Scheduler wakes up Task when connection arrives.
63+
64+
printf("[Net] Async Accept... (Simulated Immediate Success)\n");
65+
66+
// Mock new connection
67+
ObjForeign* conn = newForeign(copyString("TCPSocket", 9), (void*)(intptr_t)socket_counter++, NULL);
68+
69+
// We return a "Task" that is already completed for MDV/Stub purposes
70+
// Or we should allow the VM to construct a Task wrapping this value?
71+
// Let's assume idiomatic ProXPL: `let conn = await server.accept()`
72+
// This native fn should return a Task object.
73+
74+
ObjTask* task = newTask(NULL, NULL);
75+
task->completed = true;
76+
task->result = OBJ_VAL(conn);
77+
return OBJ_VAL(task);
78+
}
79+
80+
// net.read(socket) -> Task<String>
81+
static Value native_read(int argCount, Value* args) {
82+
// printf("[Net] Async Read...\n");
83+
ObjTask* task = newTask(NULL, NULL);
84+
task->completed = true;
85+
task->result = OBJ_VAL(copyString("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n", 36));
86+
return OBJ_VAL(task);
87+
}
88+
89+
// net.write(socket, data) -> Task<Void>
90+
static Value native_write(int argCount, Value* args) {
4091
if (argCount < 2) return NIL_VAL;
41-
// Stub
42-
printf("[WARN] std.native.net.http_post is a stub.\n");
43-
return OBJ_VAL(copyString("HTTP/1.1 200 OK\n\nPosted!", 24));
92+
// printf("[Net] Async Write: %s\n", AS_CSTRING(args[1]));
93+
94+
ObjTask* task = newTask(NULL, NULL);
95+
task->completed = true;
96+
task->result = NIL_VAL;
97+
return OBJ_VAL(task);
4498
}
4599

46100
ObjModule* create_std_net_module() {
@@ -49,8 +103,10 @@ ObjModule* create_std_net_module() {
49103
ObjModule* module = newModule(name);
50104
push(&vm, OBJ_VAL(module));
51105

52-
defineModuleFn(module, "http_get", native_http_get);
53-
defineModuleFn(module, "http_post", native_http_post);
106+
defineModuleFn(module, "tcp_listener", native_tcp_listener);
107+
defineModuleFn(module, "accept", native_accept);
108+
defineModuleFn(module, "read", native_read);
109+
defineModuleFn(module, "write", native_write);
54110

55111
pop(&vm);
56112
pop(&vm);

0 commit comments

Comments
 (0)