2021-06-21 15:38:32 +03:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdbool.h>
|
2021-09-15 21:45:44 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2021-06-13 05:37:31 +03:00
|
|
|
|
2021-09-15 21:45:44 +03:00
|
|
|
void* roc_alloc(size_t size, unsigned int alignment) { return malloc(size); }
|
2021-06-13 05:37:31 +03:00
|
|
|
|
2021-11-27 01:14:44 +03:00
|
|
|
void* roc_realloc(void* ptr, size_t new_size, size_t old_size,
|
2021-09-15 21:45:44 +03:00
|
|
|
unsigned int alignment) {
|
|
|
|
return realloc(ptr, new_size);
|
2021-06-13 05:37:31 +03:00
|
|
|
}
|
|
|
|
|
2021-09-15 21:45:44 +03:00
|
|
|
void roc_dealloc(void* ptr, unsigned int alignment) { free(ptr); }
|
2021-06-13 05:37:31 +03:00
|
|
|
|
2021-08-16 23:46:00 +03:00
|
|
|
void roc_panic(void* ptr, unsigned int alignment) {
|
2021-09-15 21:45:44 +03:00
|
|
|
char* msg = (char*)ptr;
|
|
|
|
fprintf(stderr,
|
|
|
|
"Application crashed with message\n\n %s\n\nShutting down\n", msg);
|
|
|
|
exit(0);
|
2021-08-16 23:46:00 +03:00
|
|
|
}
|
|
|
|
|
2021-09-15 21:45:44 +03:00
|
|
|
void* roc_memcpy(void* dest, const void* src, size_t n) {
|
|
|
|
return memcpy(dest, src, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
|
|
|
|
|
2021-06-13 05:37:31 +03:00
|
|
|
struct RocStr {
|
2021-09-15 21:45:44 +03:00
|
|
|
char* bytes;
|
|
|
|
size_t len;
|
2021-06-13 05:37:31 +03:00
|
|
|
};
|
|
|
|
|
2021-09-15 21:45:44 +03:00
|
|
|
bool is_small_str(struct RocStr str) { return ((ssize_t)str.len) < 0; }
|
2021-06-21 15:38:32 +03:00
|
|
|
|
|
|
|
// Determine the length of the string, taking into
|
|
|
|
// account the small string optimization
|
|
|
|
size_t roc_str_len(struct RocStr str) {
|
2021-09-15 21:45:44 +03:00
|
|
|
char* bytes = (char*)&str;
|
|
|
|
char last_byte = bytes[sizeof(str) - 1];
|
|
|
|
char last_byte_xored = last_byte ^ 0b10000000;
|
|
|
|
size_t small_len = (size_t)(last_byte_xored);
|
|
|
|
size_t big_len = str.len;
|
|
|
|
|
|
|
|
// Avoid branch misprediction costs by always
|
|
|
|
// determining both small_len and big_len,
|
|
|
|
// so this compiles to a cmov instruction.
|
|
|
|
if (is_small_str(str)) {
|
|
|
|
return small_len;
|
|
|
|
} else {
|
|
|
|
return big_len;
|
|
|
|
}
|
2021-06-21 15:38:32 +03:00
|
|
|
}
|
|
|
|
|
2021-09-19 23:05:48 +03:00
|
|
|
extern struct RocStr roc__mainForHost_1_exposed();
|
2021-06-13 05:37:31 +03:00
|
|
|
|
|
|
|
int main() {
|
2021-09-24 07:12:40 +03:00
|
|
|
struct RocStr str = roc__mainForHost_1_exposed();
|
|
|
|
|
|
|
|
// Determine str_len and the str_bytes pointer,
|
|
|
|
// taking into account the small string optimization.
|
|
|
|
size_t str_len = roc_str_len(str);
|
|
|
|
char* str_bytes;
|
|
|
|
|
|
|
|
if (is_small_str(str)) {
|
|
|
|
str_bytes = (char*)&str;
|
|
|
|
} else {
|
|
|
|
str_bytes = str.bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write to stdout
|
|
|
|
if (write(1, str_bytes, str_len) >= 0) {
|
|
|
|
// Writing succeeded!
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
printf("Error writing to stdout: %s\n", strerror(errno));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2021-06-13 05:37:31 +03:00
|
|
|
}
|