Skip to content

Commit

Permalink
[cu] readback arbitrary-sized bytes and str
Browse files Browse the repository at this point in the history
  • Loading branch information
enricozb committed Jun 24, 2024
1 parent e488f35 commit 3a8de54
Showing 1 changed file with 46 additions and 61 deletions.
107 changes: 46 additions & 61 deletions src/run.cu
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ struct Tup {

// Readback: λ-Encoded Str (UTF-32)
// FIXME: this is actually ASCII :|
// FIXME: remove len limit
struct Str {
u32 text_len;
char text_buf[256];
u32 len;
char* buf;
};

// Readback: λ-Encoded list of bytes
Expand All @@ -27,8 +26,6 @@ typedef struct Bytes {
char *buf;
} Bytes;

#define MAX_BYTES 256

// IO Magic Number
#define IO_MAGIC_0 0xD0CA11
#define IO_MAGIC_1 0xFF1FF1
Expand Down Expand Up @@ -99,16 +96,15 @@ Tup gnet_readback_tup(GNet* gnet, Port port, u32 size) {
}


// Reads back a UTF-32 (truncated to 24 bits) string.
// Since unicode scalars can fit in 21 bits, HVM's u24
// integers can contain any unicode scalar value.
// Converts a Port into a list of bytes.
// Encoding:
// - λt (t NIL)
// - λt (((t CONS) head) tail)
Str gnet_readback_str(GNet* gnet, Port port) {
// Result
Str str;
str.text_len = 0;
Bytes gnet_readback_bytes(GNet* gnet, Port port) {
Bytes bytes;
u32 capacity = 256;
bytes.buf = (char*) malloc(sizeof(char) * capacity);
bytes.len = 0;

// Readback loop
while (TRUE) {
Expand All @@ -126,12 +122,15 @@ Str gnet_readback_str(GNet* gnet, Port port) {
case LIST_CONS: {
if (ctr.args_len != 2) break;
if (get_tag(ctr.args_buf[0]) != NUM) break;
if (str.text_len >= 255) {
printf("ERROR: for now, HVM can only readback strings of length <256.");
break;
if (bytes.len == capacity - 1) {
capacity *= 2;
char* new_buf = (char*)malloc(sizeof(char) * capacity);
memcpy(new_buf, bytes.buf, bytes.len);
free(bytes.buf);
bytes.buf = new_buf;
}

str.text_buf[str.text_len++] = get_u24(get_val(ctr.args_buf[0]));
bytes.buf[bytes.len++] = get_u24(get_val(ctr.args_buf[0]));
gnet_boot_redex(gnet, new_pair(ctr.args_buf[1], ROOT));
port = ROOT;
continue;
Expand All @@ -140,56 +139,29 @@ Str gnet_readback_str(GNet* gnet, Port port) {
break;
}

str.text_buf[str.text_len] = '\0';

return str;
return bytes;
}

// Converts a Port into a list of bytes.
// Reads back a UTF-32 (truncated to 24 bits) string.
// Since unicode scalars can fit in 21 bits, HVM's u24
// integers can contain any unicode scalar value.
// Encoding:
// - λt (t NIL)
// - λt (((t CONS) head) tail)
Bytes gnet_readback_bytes(GNet* gnet, Port port) {
// Result
Bytes bytes;
bytes.buf = (char*) malloc(sizeof(char) * MAX_BYTES);
bytes.len = 0;

// Readback loop
while (TRUE) {
// Normalizes the net
gnet_normalize(gnet);

// Reads the λ-Encoded Ctr
Ctr ctr = gnet_readback_ctr(gnet, gnet_peek(gnet, port));

// Reads string layer
switch (ctr.tag) {
case LIST_NIL: {
break;
}
case LIST_CONS: {
if (ctr.args_len != 2) break;
if (get_tag(ctr.args_buf[0]) != NUM) break;
if (bytes.len >= MAX_BYTES) {
printf("ERROR: for now, HVM can only readback list of bytes of length <%u.", MAX_BYTES);
break;
}

bytes.buf[bytes.len++] = get_u24(get_val(ctr.args_buf[0]));
gnet_boot_redex(gnet, new_pair(ctr.args_buf[1], ROOT));
port = ROOT;
continue;
}
}
break;
}
Str gnet_readback_str(GNet* gnet, Port port) {
// gnet_readback_bytes is guaranteed to return a buffer with a capacity of at least one more
// than the number of bytes read, so we can null-terminate it.
Bytes bytes = gnet_readback_bytes(gnet, port);

bytes.buf[bytes.len] = '\0';
Str str;
str.len = bytes.len;
str.buf = bytes.buf;
str.buf[str.len] = 0;

return bytes;
return str;
}


/// Returns a λ-Encoded Ctr for a NIL: λt (t NIL)
/// Should only be called within `inject_bytes`, as a previous call
/// to `get_resources` is expected.
Expand Down Expand Up @@ -374,12 +346,20 @@ Port io_open(GNet* gnet, Port argm) {

for (u32 fd = 3; fd < sizeof(FILE_POINTERS); fd++) {
if (FILE_POINTERS[fd] == NULL) {
FILE_POINTERS[fd] = fopen(name.text_buf, mode.text_buf);
FILE_POINTERS[fd] = fopen(name.buf, mode.buf);

free(name.buf);
free(mode.buf);

return new_port(NUM, new_u24(fd));
}
}

fprintf(stderr, "io_open: too many open files\n");

free(name.buf);
free(mode.buf);

return new_port(ERA, 0);
}

Expand Down Expand Up @@ -573,18 +553,23 @@ void do_run_io(GNet* gnet, Book* book, Port port) {
FFn* ffn = NULL;
// FIXME: optimize this linear search
for (u32 fid = 0; fid < book->ffns_len; ++fid) {
if (strcmp(func.text_buf, book->ffns_buf[fid].name) == 0) {
if (strcmp(func.buf, book->ffns_buf[fid].name) == 0) {
ffn = &book->ffns_buf[fid];
break;
}
}

if (ffn == NULL) {
fprintf(stderr, "Unknown IO func '%s'\n", func.text_buf);
fprintf(stderr, "Unknown IO func '%s'\n", func.buf);

free(func.buf);

break;
}

debug("running io func '%s'\n", func.text_buf);
debug("running io func '%s'\n", func.buf);

free(func.buf);

Port argm = ctr.args_buf[2];
Port cont = ctr.args_buf[3];
Expand Down

0 comments on commit 3a8de54

Please sign in to comment.