aboutsummaryrefslogtreecommitdiff
path: root/moonshine.h
diff options
context:
space:
mode:
Diffstat (limited to 'moonshine.h')
-rw-r--r--moonshine.h104
1 files changed, 76 insertions, 28 deletions
diff --git a/moonshine.h b/moonshine.h
index eb47a6c..19c125a 100644
--- a/moonshine.h
+++ b/moonshine.h
@@ -38,8 +38,9 @@
}
#define instance(__type, kind, ...) ((struct __type) { .type = cat(kind, _type), .data.kind = { __VA_ARGS__ } })
#define scope(name, ...) \
- for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; datatype_break == (typeof(name)) 0; \
- datatype_break = (typeof(name)) 1)
+ _Pragma("unroll") for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; \
+ datatype_break == (typeof(name)) 0; \
+ datatype_break = (typeof(name)) 1)
#define match(value) scope(parent_value, &value) switch (parent_value->type)
#define algebra_field_sum(extra, time, field) +sizeof(cat(extra, field))
#define algebra_of_field(extra, time, field) scope(field, ({ parent_value->data.extra.cat4(object_type_, extra, _, time); }))
@@ -1085,17 +1086,16 @@ void unsafe_push(var *array, const var ptr, const u4 ptr_size) [[clang::allocati
__attribute__((deprecated(LIBC_WARNINGS_TEXT("strdup"))))
#endif
-__attribute__((diagnose_as_builtin(__builtin_strdup, 1)))
-t(char) strdup(ctring str) {
- const u8 len = strlen(str);
- const auto obj = new (char, len + 1);
+// ctring strdup(ctring str) {
+// const u8 len = strlen(str);
+// string obj = alloc(len + 1);
- for (u8 i = 0; i < len; i++) obj[ 0 ][ i ] = str[ i ];
+// for (u8 i = 0; i < len; i++) obj[ i ] = str[ i ];
- obj[ 0 ][ len ] = 0;
+// obj[ len ] = 0;
- return obj;
-}
+// return obj;
+// }
var *__reverse_array(var *array) {
const u4 element_size = element_size(array);
@@ -1188,29 +1188,41 @@ linkednode *index_to_ptr(linkedlist *list, u8 index) {
else if (index == last - 2) return list->tail->back[ 1 ];
// clang-format on
+ linkednode *current;
+ u8 current_index;
+
// decide whether to start from the head or the tail of the list
- if (index < (last / 2)) { // start from the head
- byte body = 0;
- auto start = list->head->front[ 1 ]->front;
- for (u8 i = 3; i <= index; i++) {
- if (start[ body ] == NULL) return NULL;
- if (i == index) return start[ body ];
- if (body) start = start[ 1 ]->front;
- body = 1 - body;
+ if (index <= (last / 2)) { // start from the head
+ current = list->head;
+ current_index = 0;
+ while (current && current_index < index) {
+ if (current->front[ 1 ] && current_index + 2 <= index) {
+ current = current->front[ 1 ];
+ current_index += 2;
+ } else if (current->front[ 0 ]) {
+ current = current->front[ 0 ];
+ current_index += 1;
+ } else {
+ break;
+ }
}
} else { // start from the tail
- byte body = 0;
- auto end = list->tail->back[ 1 ]->back;
- for (u8 i = last - 3; i >= index; i--) {
- if (end[ body ] == NULL) return NULL;
- if (i == index) return end[ body ];
- if (i == 0) return NULL;
- if (body) end = end[ 1 ]->back;
- body = 1 - body;
+ current = list->tail;
+ current_index = list->size - 1;
+ while (current && current_index > index) {
+ if (current->back[ 1 ] && current_index - 2 >= index) {
+ current = current->back[ 1 ];
+ current_index -= 2;
+ } else if (current->back[ 0 ]) {
+ current = current->back[ 0 ];
+ current_index -= 1;
+ } else {
+ break;
+ }
}
}
- return NULL;
+ return (current_index == index) ? current : NULL;
}
// This function will return a pointer to the linkednode, if free = false, and a pointer to the data contained inside, if free =
@@ -1234,6 +1246,8 @@ overload var pop_item(linkedlist *list, bool free, linkednode *item) {
item->front[ 0 ] = item->front[ 1 ] = item->back[ 0 ] = item->back[ 1 ] = 0;
+ list->size--;
+
auto ptr = item->data;
if (free) {
release(item);
@@ -1263,7 +1277,19 @@ line void front_insert(linkedlist *list, u8 index) { return front_insert(list, i
string *environ;
-[[noreturn]] void __moonshine_start(int argc, string *argv, string *envp) {
+#ifdef __MOONSHINE_PROFILER
+extern void __llvm_profile_reset_counters(void);
+extern int __llvm_profile_write_file(void);
+extern void __llvm_profile_set_filename(const char *name);
+#endif
+
+[[noreturn]] __attribute__((used)) void __moonshine_start(int argc, string *argv, string *envp) {
+#ifdef __MOONSHINE_PROFILER
+ static const char profile_filename[] __attribute__((used)) = "profile.profraw";
+ __llvm_profile_reset_counters();
+ __llvm_profile_set_filename(profile_filename);
+#endif
+
global_page_table = PageTable();
environ = envp;
@@ -1277,7 +1303,13 @@ string *environ;
: "r"((long) argc), "r"(argv)
: "rdi", "rsi", "rax", "memory");
+#ifdef __MOONSHINE_PROFILER
+ extern int __llvm_profile_write_file(void);
+ __llvm_profile_write_file();
+#endif
+
exit(exit_code);
+ __builtin_unreachable();
}
__attribute__((force_align_arg_pointer)) __attribute__((naked)) void _start(void) {
@@ -1357,7 +1389,11 @@ FILE *fopen(const char *pathname, const char *mode) {
int fd = syscall5(SYS_openat, AT_FDCWD, pathname, flags, perms);
if (fd < 0) return 0;
+#ifdef __MOONSHINE_PROFILER
+ FILE *file = (FILE *) __bare_alloc(sizeof(FILE));
+#else
FILE *file = (FILE *) alloc(sizeof(FILE));
+#endif
if (!file) {
(void) syscall2(SYS_close, fd);
return 0;
@@ -1381,7 +1417,11 @@ size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
int fclose(FILE *stream) {
if (!stream) return -1;
int ret = syscall2(SYS_close, stream->fd);
+#ifdef __MOONSHINE_PROFILER
+ __bare_munmap((var) stream, sizeof(FILE));
+#else
release((var) stream);
+#endif
return (ret < 0) ? -1 : 0;
}
@@ -1406,4 +1446,12 @@ size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
long ftell(FILE *stream) { return syscall4(SYS_lseek, stream->fd, 0, SEEK_CUR); }
+#ifdef __MOONSHINE_PROFILER
+void *__dso_handle = (void *) 0;
+int atexit(void (*func)(void)) {
+ func(); // Call immediately since we don’t buffer exits
+ return 0;
+}
+#endif
+
#endif