start creating base objects for runtime

This commit is contained in:
2025-06-24 01:55:01 +01:00
parent 74c71c3a1b
commit 498cd39c04
16 changed files with 414 additions and 153 deletions

View File

@@ -74,6 +74,10 @@ int main(int argc, char *argv[]) {
fclose(file); fclose(file);
generate_siphash_key();
init_types();
runtime(translated); runtime(translated);
free_translator(&translated); free_translator(&translated);

View File

@@ -33,7 +33,6 @@ void gmp_gc_free(void *ptr, size_t size) {
void ar_memory_init() { void ar_memory_init() {
GC_INIT(); GC_INIT();
mp_set_memory_functions(GC_malloc, gmp_gc_realloc, gmp_gc_free); mp_set_memory_functions(GC_malloc, gmp_gc_realloc, gmp_gc_free);
init_type_obj();
} }

View File

@@ -1,143 +1,112 @@
#include "hashmap.h" #include "hashmap.h"
#include <stdint.h>
#include <gc/gc.h>
#include <stdlib.h>
#include "../../../memory.h" #include "../../../memory.h"
#include <gc/gc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct hashmap *createHashmap(int size) struct hashmap *createHashmap() {
{ size_t size = 8;
struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap)); struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap));
t->size = size; t->size = size;
t->list = (struct node **)ar_alloc(sizeof(struct node *) * size); t->order = 1;
int i; t->list = (struct node **)ar_alloc(sizeof(struct node *) * size);
for (i = 0; i < size; i++) memset(t->list, 0, sizeof(struct node *) * size);
t->list[i] = NULL; return t;
return t;
} }
void resize_hashmap(struct hashmap *t) void resize_hashmap(struct hashmap *t) {
{ int old_size = t->size;
int old_size = t->size; int new_size = old_size * 2;
int new_size = old_size * 2;
struct node **old_list = t->list; struct node **old_list = t->list;
// Create new list // Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size); t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
for (int i = 0; i < new_size; i++) memset(t->list, 0, sizeof(struct node *) * new_size);
t->list[i] = NULL;
t->size = new_size; t->size = new_size;
t->count = 0; t->count = 0;
// Rehash old entries into new list // Rehash old entries into new list
for (int i = 0; i < old_size; i++) { for (int i = 0; i < old_size; i++) {
struct node *temp = old_list[i]; struct node *temp = old_list[i];
while (temp) { while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val); // Will increment count hashmap_insert(t, temp->hash, temp->key, temp->val,
temp = temp->next; temp->order); // Will increment count
} temp = temp->next;
} }
}
} }
int hashCode(struct hashmap *t, uint64_t hash) int hashCode(struct hashmap *t, uint64_t hash) { return hash % t->size; }
{
return hash % t->size; int hashmap_remove(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
struct node *prev = NULL;
while (temp) {
if (temp->hash == hash) {
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
return 1;
}
prev = temp;
temp = temp->next;
}
list = NULL;
prev = NULL;
temp = NULL;
return 0;
} }
int hashmap_remove(struct hashmap *t, uint64_t hash) void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
{ void *val, size_t order) {
int pos = hashCode(t, hash); if (!order) {
struct node *list = t->list[pos]; order = t->order++;
struct node *temp = list; }
struct node *prev = NULL; if ((t->count + 1) > t->size * 0.75) {
while (temp) resize_hashmap(t);
{ }
if (temp->hash == hash)
{
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
free(temp); int pos = hashCode(t, hash);
return 1; struct node *list = t->list[pos];
} struct node *temp = list;
prev = temp;
temp = temp->next; // Check if key exists → overwrite
while (temp) {
if (temp->hash == hash) {
temp->val = val;
return;
} }
return 0; temp = temp->next;
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
newNode->order = order;
newNode->next = list;
t->list[pos] = newNode;
t->count++;
} }
void resize(struct hashmap *t) void *hashmap_lookup(struct hashmap *t, uint64_t hash) {
{ int pos = hashCode(t, hash);
int old_size = t->size; struct node *list = t->list[pos];
int new_size = old_size * 2; struct node *temp = list;
while (temp) {
struct node **old_list = t->list; if (temp->hash == hash) {
return temp->val;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
for (int i = 0; i < new_size; i++)
t->list[i] = NULL;
t->size = new_size;
t->count = 0;
// Rehash old entries into new list
for (int i = 0; i < old_size; i++) {
struct node *temp = old_list[i];
while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val); // Will increment count
temp = temp->next;
}
} }
} temp = temp->next;
}
void hashmap_insert(struct hashmap *t, uint64_t hash, ArgonObject* key, ArgonObject* val) return NULL;
{
if ((t->count + 1) > t->size * 0.75) {
resize(t);
}
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
// Check if key exists → overwrite
while (temp)
{
if (temp->key == key)
{
temp->val = val;
return;
}
temp = temp->next;
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
newNode->next = list;
t->list[pos] = newNode;
t->count++;
}
void *lookup(struct hashmap *t, uint64_t hash)
{
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
while (temp)
{
if (temp->hash == hash)
{
return temp->val;
}
temp = temp->next;
}
return NULL;
} }

View File

@@ -5,26 +5,29 @@
typedef struct ArgonObject ArgonObject; typedef struct ArgonObject ArgonObject;
struct node struct node {
{ uint64_t hash;
uint64_t hash; void *key;
ArgonObject *key; void *val;
ArgonObject *val; size_t order;
struct node *next; struct node *next;
}; };
struct hashmap struct hashmap {
{ size_t size;
size_t size; size_t count;
size_t count; size_t order;
struct node **list; struct node **list;
}; };
struct hashmap *createHashmap(int size); struct hashmap *createHashmap();
int hashCode(struct hashmap *t, uint64_t hash); int hashCode(struct hashmap *t, uint64_t hash);
int hashmap_remove(struct hashmap *t, uint64_t hash); int hashmap_remove(struct hashmap *t, uint64_t hash);
void hashmap_insert(struct hashmap *t, uint64_t hash, ArgonObject* key, ArgonObject* val); void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void *val, size_t order);
void *hashmap_lookup(struct hashmap *t, uint64_t hash);
#endif // HASHMAP_H #endif // HASHMAP_H

View File

@@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../memory.h" #include "../../../memory.h"
LinkedList *create_list(size_t data_size) { LinkedList *create_list(size_t data_size) {
LinkedList *list = checked_malloc(sizeof(LinkedList)); LinkedList *list = checked_malloc(sizeof(LinkedList));

View File

@@ -0,0 +1,185 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2022 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "siphash.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
/* default: SipHash-2-4 */
#ifndef cROUNDS
#define cROUNDS 2
#endif
#ifndef dROUNDS
#define dROUNDS 4
#endif
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG_SIPHASH
#include <stdio.h>
#define TRACE \
do { \
printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
} while (0)
#else
#define TRACE
#endif
/*
Computes a SipHash value
*in: pointer to input data (read-only)
inlen: input data length in bytes (any size_t value)
*k: pointer to the key data (read-only), must be 16 bytes
*out: pointer to output data (write-only), outlen bytes must be allocated
outlen: length of the output in bytes, must be 8 or 16
*/
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen) {
const unsigned char *ni = (const unsigned char *)in;
const unsigned char *kk = (const unsigned char *)k;
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
uint64_t k0 = U8TO64_LE(kk);
uint64_t k1 = U8TO64_LE(kk + 8);
uint64_t m;
int i;
const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; ni != end; ni += 8) {
m = U8TO64_LE(ni);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)ni[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((uint64_t)ni[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((uint64_t)ni[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((uint64_t)ni[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((uint64_t)ni[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((uint64_t)ni[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((uint64_t)ni[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}

View File

@@ -0,0 +1,22 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2021 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <inttypes.h>
#include <string.h>
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen);

View File

@@ -1,9 +1,17 @@
#include "object.h" #include "object.h"
#include "../../memory.h" #include "../../memory.h"
#include "../runtime.h"
#include <string.h>
ArgonObject* init_argon_object() { ArgonObject* init_argon_object() {
ArgonObject *object = ar_alloc(sizeof(ArgonObject)); ArgonObject *object = ar_alloc(sizeof(ArgonObject));
object->type = TYPE_OBJECT; object->type = TYPE_OBJECT;
object->cls = object; object->typeObject = NULL;
object->fields = createHashmap(8); object->fields = createHashmap();
memset(&object->value, 0, sizeof(object->value));
return object;
}
void add_field(ArgonObject*target, char* name, ArgonObject *object) {
hashmap_insert(target->fields, siphash64_bytes(name, strlen(name)),name, object, 0);
} }

View File

@@ -4,6 +4,11 @@
#include <gmp.h> #include <gmp.h>
#include <stdbool.h> #include <stdbool.h>
struct string_struct {
char *data;
size_t length;
};
typedef enum { typedef enum {
TYPE_NULL, TYPE_NULL,
TYPE_BOOL, TYPE_BOOL,
@@ -16,14 +21,19 @@ typedef enum {
struct ArgonObject { struct ArgonObject {
ArgonType type; ArgonType type;
struct ArgonObject *cls; // class pointer or type object ArgonObject *typeObject;
struct hashmap *fields; // dynamic fields/methods struct hashmap *fields; // dynamic fields/methods
union { union {
mpq_t as_number; mpq_t as_number;
bool as_bool; bool as_bool;
char *as_str; struct string_struct as_str;
void *native_fn; void *native_fn;
// others as needed // others as needed
} value; } value;
}; };
typedef struct ArgonObject ArgonObject;
ArgonObject *init_argon_object();
void add_field(ArgonObject*target, char* name, ArgonObject *object);
#endif // OBJECT_H #endif // OBJECT_H

View File

@@ -0,0 +1,16 @@
#include "../object.h"
#include <stdint.h>
ArgonObject *ARGON_STRING_TYPE = NULL;
void init_string_type() {
ARGON_STRING_TYPE = init_argon_object();
}
ArgonObject *init_string_object(char*data, size_t length) {
ArgonObject * object = init_argon_object();
object->typeObject = ARGON_STRING_TYPE;
object->value.as_str.data = data;
object->value.as_str.length = length;
return object;
}

View File

@@ -0,0 +1,11 @@
#ifndef STRING_OBJ_H
#define STRING_OBJ_H
#include "../object.h"
extern ArgonObject *ARGON_STRING_TYPE;
void init_string_type();
ArgonObject *init_string_object(char*data, size_t length);
#endif // STRING_OBJ_H

View File

@@ -1,15 +1,10 @@
#include "../object.h"
#include "../../internals/hashmap/hashmap.h" #include "../../internals/hashmap/hashmap.h"
#include "../../../memory.h" #include "../object.h"
#include <string.h> #include <string.h>
#include "type.h" #include "type.h"
ArgonObject *ARGON_TYPE_OBJ = NULL; ArgonObject *ARGON_TYPE = NULL;
void init_type_obj() { void init_type() {
ARGON_TYPE_OBJ = ar_alloc(sizeof(ArgonObject)); ARGON_TYPE = init_argon_object();
ARGON_TYPE_OBJ->type = TYPE_OBJECT;
ARGON_TYPE_OBJ->cls = ARGON_TYPE_OBJ;
ARGON_TYPE_OBJ->fields = createHashmap(8);
memset(&ARGON_TYPE_OBJ->value, 0, sizeof(ARGON_TYPE_OBJ->value));
} }

View File

@@ -2,9 +2,9 @@
#define TYPES_H #define TYPES_H
#include "../object.h" #include "../object.h"
extern ArgonObject *ARGON_TYPE_OBJ; extern ArgonObject *ARGON_TYPE;
void init_type_obj(); void init_type();
#endif // TYPES_H #endif // TYPES_H

View File

@@ -3,6 +3,16 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "internals/siphash/siphash.h"
#include "objects/type/type.h"
#include "objects/string/string.h"
void init_types() {
init_type();
init_string_type();
}
uint64_t pop_bytecode(Translated *translated, RuntimeState *state) { uint64_t pop_bytecode(Translated *translated, RuntimeState *state) {
uint64_t *instruction = darray_get(&translated->bytecode, state->head++); uint64_t *instruction = darray_get(&translated->bytecode, state->head++);
@@ -21,4 +31,28 @@ void runtime(Translated translated) {
while (state.head < translated.bytecode.size) while (state.head < translated.bytecode.size)
run_instruction(&translated, &state); run_instruction(&translated, &state);
free(state.registers); free(state.registers);
}
static uint8_t siphash_key[16];
void generate_siphash_key() {
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0 || read(fd, siphash_key, 16) != 16) {
// Fallback or abort
}
close(fd);
}
uint64_t siphash64_bytes(const void *data, size_t len) {
uint8_t out[8];
if (siphash(data, len, siphash_key, out, sizeof(out)) != 0)
return 0;
uint64_t hash = 0;
for (int i = 0; i < 8; ++i)
hash |= ((uint64_t)out[i]) << (8 * i);
return hash;
} }

View File

@@ -7,9 +7,14 @@ typedef struct {
size_t head; size_t head;
} RuntimeState; } RuntimeState;
void init_types();
void run_instruction(Translated *translated, RuntimeState *state); void run_instruction(Translated *translated, RuntimeState *state);
void runtime(Translated translated); void runtime(Translated translated);
uint64_t siphash64_bytes(const void *data, size_t len);
void generate_siphash_key();
#endif // RUNTIME_H #endif // RUNTIME_H