// Values: the types that every other part uses, the allocator and errors. // An object is a struct of its class, which the emitted C defines, and every // pointer to one is a real object: undefined and null are values of their own #pragma once #include #include #include typedef struct { char _; } undefined_t; typedef struct { char _; } null_t; // A string: UTF-16 code units, as JS counts them typedef struct jsrt_string *string_t; // A new heap cell of `size` bytes, all zero void *__rt_alloc(size_t size); // `items`, an array's elements of `size` bytes each, with room for at least // `need` of them. `*cap` is the room that it has, and is set to the new room. // The new room is all zero void *__rt_grow(void *items, int32_t *cap, int32_t need, size_t size); // Throws a TypeError, which says `what`. Exceptions are not supported yet, so // it stops the program _Noreturn void __rt_type_error(const char *what); #ifdef JSRT_IMPLEMENTATION #include #include #include void *__rt_alloc(size_t size) { void *p = calloc(1, size); if (!p) { fputs("jsrt: out of memory\n", stderr); abort(); } return p; } void *__rt_grow(void *items, int32_t *cap, int32_t need, size_t size) { if (need <= *cap) { return items; } int32_t room = *cap * 2 > need ? *cap * 2 : need < 4 ? 4 : need; items = realloc(items, (size_t)room * size); if (!items) { fputs("jsrt: out of memory\n", stderr); abort(); } memset((char *)items + (size_t)*cap * size, 0, (size_t)(room - *cap) * size); *cap = room; return items; } _Noreturn void __rt_type_error(const char *what) { fprintf(stderr, "TypeError: %s\n", what); exit(1); } #endif // JSRT_IMPLEMENTATION