From 4cf95336e80e28b0828b26fe93e78cb18684731c Mon Sep 17 00:00:00 2001 From: cozis Date: Sat, 4 Dec 2021 12:36:47 +0100 Subject: [PATCH] added network builtins and fixed a bug in OPCODE_SELECT --- build.sh | 4 +- samples/buffer.noja | 16 ++- samples/socket.noja | 9 ++ src/o_builtins.c | 19 ++-- src/o_network_builtins.c | 218 +++++++++++++++++++++++++++++++++++++++ src/objects/o_buffer.c | 5 +- src/runtime/runtime.c | 7 +- 7 files changed, 265 insertions(+), 13 deletions(-) create mode 100644 samples/socket.noja create mode 100644 src/o_network_builtins.c diff --git a/build.sh b/build.sh index bb6aff2..958ddd4 100755 --- a/build.sh +++ b/build.sh @@ -40,7 +40,8 @@ gcc -c src/runtime/runtime.c -o temp/runtime/runtime.o $FLAGS gcc -c src/runtime/o_nfunc.c -o temp/runtime/o_nfunc.o $FLAGS gcc -c src/runtime/o_func.c -o temp/runtime/o_func.o $FLAGS -gcc -c src/o_builtins.c -o temp/o_builtins.o $FLAGS +gcc -c src/o_builtins.c -o temp/o_builtins.o $FLAGS +gcc -c src/o_network_builtins.c -o temp/o_network_builtins.o $FLAGS rm -rf build mkdir build @@ -73,6 +74,7 @@ gcc tests/src/test-objects.c -o build/test-objects $FLAGS -Lbuild/ -lnoja-object gcc src/main.c \ src/debug.c \ temp/o_builtins.o \ + temp/o_network_builtins.o \ temp/utils/hash.o \ temp/utils/stack.o \ temp/utils/source.o \ diff --git a/samples/buffer.noja b/samples/buffer.noja index 537bea9..5130597 100644 --- a/samples/buffer.noja +++ b/samples/buffer.noja @@ -3,4 +3,18 @@ b = newBuffer(16); b[2] = 10; -print(b); \ No newline at end of file +print(b, '\n'); + +fun toArray(buffer) + { + i = 0; + r = []; + while i < count(buffer): + { + r[i] = buffer[i]; + i = i+1; + } + return r; + } + +print(toArray(b), '\n'); diff --git a/samples/socket.noja b/samples/socket.noja new file mode 100644 index 0000000..f0ed191 --- /dev/null +++ b/samples/socket.noja @@ -0,0 +1,9 @@ + +print('test 0\n'); + +print('SOCK_STREAM = ', network.SOCK_STREAM, ';\n'); + +print('test 1\n'); + +fd = network.socket(network.AF_INET, network.SOCK_STREAM, 0); +print(fd); \ No newline at end of file diff --git a/src/o_builtins.c b/src/o_builtins.c index 8981811..6ee1c6c 100644 --- a/src/o_builtins.c +++ b/src/o_builtins.c @@ -5,8 +5,9 @@ #include "runtime/runtime.h" #include "utils/defs.h" +Object *Object_NewNetworkBuiltinsMap(Runtime *runtime, Heap *heap, Error *err); + static Object *select_(Object *self, Object *key, Heap *heap, Error *err); -static int count(Object *self); static Object *bin_print (Runtime *runtime, Object **argv, unsigned int argc, Error *error); static Object *bin_count (Runtime *runtime, Object **argv, unsigned int argc, Error *error); @@ -24,8 +25,6 @@ static const Type t_builtins_map = { .name = "builtins map", .size = sizeof(BuiltinsMapOjbect), .select = select_, - .count = count, - .print = NULL, }; static Object *select_(Object *self, Object *key, Heap *heap, Error *err) @@ -80,6 +79,14 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *err) return NULL; } + case PAIR(sizeof("network")-1, 'n'): + { + if(!strcmp(s, "network")) + return Object_NewNetworkBuiltinsMap(bm->runtime, heap, err); + + return NULL; + } + case PAIR(sizeof("newBuffer")-1, 'n'): { if(!strcmp(s, "newBuffer")) @@ -93,12 +100,6 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *err) return NULL; } -static int count(Object *self) -{ - (void) self; - return 3; -} - Object *Object_NewBuiltinsMap(Runtime *runtime, Heap *heap, Error *err) { BuiltinsMapOjbect *bm = (BuiltinsMapOjbect*) Heap_Malloc(heap, &t_builtins_map, err); diff --git a/src/o_network_builtins.c b/src/o_network_builtins.c new file mode 100644 index 0000000..5b35596 --- /dev/null +++ b/src/o_network_builtins.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include +#include "runtime/runtime.h" +#include "utils/defs.h" + +static Object *select_(Object *self, Object *key, Heap *heap, Error *err); + +static Object *bin_socket(Runtime *runtime, Object **argv, unsigned int argc, Error *error); + +typedef struct { + Object base; + Runtime *runtime; +} NetworkBuiltinsMapOjbect; + +static const Type t_builtins_map = { + .base = (Object) { .type = &t_type, .flags = Object_STATIC }, + .name = "network builtins map", + .size = sizeof(NetworkBuiltinsMapOjbect), + .select = select_, +}; + +static Object *select_(Object *self, Object *key, Heap *heap, Error *err) +{ + NetworkBuiltinsMapOjbect *bm = (NetworkBuiltinsMapOjbect*) self; + + if(!Object_IsString(key)) + { + Error_Report(err, 0, "Non string key"); + return NULL; + } + + int n; + const char *s; + + s = Object_ToString(key, &n, heap, err); + + if(s == NULL) + return NULL; + + #define PAIR(p, q) \ + (((uint64_t) (p) << 32) | (uint32_t) (q)) + + switch(PAIR(n, s[0])) + { + case PAIR(6, 's'): + { + if(!strcmp(s, "socket")) + return Object_FromNativeFunction(bm->runtime, bin_socket, 3, heap, err); + return NULL; + } + + case PAIR(5, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "IB")) + return Object_FromInt(AF_IB, heap, err); + } + return NULL; + } + + case PAIR(6, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "IPX")) + return Object_FromInt(AF_IPX, heap, err); + + if(!strcmp(s+3, "X25")) + return Object_FromInt(AF_X25, heap, err); + + if(!strcmp(s+3, "KEY")) + return Object_FromInt(AF_KEY, heap, err); + + if(!strcmp(s+3, "RDS")) + return Object_FromInt(AF_RDS, heap, err); + + if(!strcmp(s+3, "LLC")) + return Object_FromInt(AF_LLC, heap, err); + + if(!strcmp(s+3, "CAN")) + return Object_FromInt(AF_CAN, heap, err); + + if(!strcmp(s+3, "ALG")) + return Object_FromInt(AF_ALG, heap, err); + + if(!strcmp(s+3, "KCM")) + return Object_FromInt(AF_KCM, heap, err); + + if(!strcmp(s+3, "XDP")) + return Object_FromInt(AF_XDP, heap, err); + } + return NULL; + } + + case PAIR(7, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "UNIX")) + return Object_FromInt(AF_UNIX, heap, err); + + if(!strcmp(s+3, "INET")) + return Object_FromInt(AF_INET, heap, err); + + if(!strcmp(s+3, "AX25")) + return Object_FromInt(AF_AX25, heap, err); + + if(!strcmp(s+3, "MPLS")) + return Object_FromInt(AF_MPLS, heap, err); + + if(!strcmp(s+3, "TIPC")) + return Object_FromInt(AF_TIPC, heap, err); + } + return NULL; + } + + case PAIR(8, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "LOCAL")) + return Object_FromInt(AF_LOCAL, heap, err); + + if(!strcmp(s+3, "INET6")) + return Object_FromInt(AF_INET6, heap, err); + + if(!strcmp(s+3, "PPPOX")) + return Object_FromInt(AF_PPPOX, heap, err); + + if(!strcmp(s+3, "VSOCK")) + return Object_FromInt(AF_VSOCK, heap, err); + } + return NULL; + } + + case PAIR(9, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "DECnet")) + return Object_FromInt(AF_DECnet, heap, err); + + if(!strcmp(s+3, "PACKET")) + return Object_FromInt(AF_PACKET, heap, err); + } + return NULL; + } + + case PAIR(10, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "NETLINK")) + return Object_FromInt(AF_NETLINK, heap, err); + } + return NULL; + } + + case PAIR(12, 'A'): + { + if(s[1] == 'F' && s[2] == '_') + { + if(!strcmp(s+3, "BLUETOOTH")) + return Object_FromInt(AF_BLUETOOTH, heap, err); + + if(!strcmp(s+3, "APPLETALK")) + return Object_FromInt(AF_APPLETALK, heap, err); + } + return NULL; + } + } + + // Not found. + return NULL; +} + +Object *Object_NewNetworkBuiltinsMap(Runtime *runtime, Heap *heap, Error *err) +{ + NetworkBuiltinsMapOjbect *bm = (NetworkBuiltinsMapOjbect*) Heap_Malloc(heap, &t_builtins_map, err); + + if(bm == NULL) + return NULL; + + bm->runtime = runtime; + + return (Object*) bm; +} + +static Object *bin_socket(Runtime *runtime, Object **argv, unsigned int argc, Error *error) +{ + assert(argc == 3); + + int domain, type, protocol; + + domain = Object_ToInt(argv[0], error); + if(error->occurred == 1) return NULL; + + type = Object_ToInt(argv[1], error); + if(error->occurred == 1) return NULL; + + protocol = Object_ToInt(argv[2], error); + if(error->occurred == 1) return NULL; + + int fd = socket(domain, type, protocol); + + if(fd < 0) + { + Error_Report(error, 0, "Failed to create socket (%s)", strerror(errno)); + return NULL; + } + + return Object_FromInt(fd, Runtime_GetHeap(runtime), error); +} \ No newline at end of file diff --git a/src/objects/o_buffer.c b/src/objects/o_buffer.c index a8a1ca0..22d2a2b 100644 --- a/src/objects/o_buffer.c +++ b/src/objects/o_buffer.c @@ -1,4 +1,5 @@ #include +#include #include "../utils/defs.h" #include "objects.h" @@ -40,6 +41,8 @@ Object *Object_NewBuffer(int size, Heap *heap, Error *error) if(obj->body == NULL) return NULL; + + memset(obj->body, 0, size); } return (Object*) obj; @@ -71,7 +74,7 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error) } unsigned char byte = buffer->body[idx]; - + return Object_FromInt(byte, heap, error); } diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 7d9d5cf..812bdf4 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -713,7 +713,12 @@ static _Bool step(Runtime *runtime, Error *error) Object *val = Object_Select(col, key, runtime->heap, error); if(val == NULL) - return 0; + { + val = Object_NewNone(runtime->heap, error); + + if(val == NULL) + return 0; + } if(!Runtime_Push(runtime, error, val)) return 0;