Add basic print program

This commit is contained in:
2025-12-02 22:38:22 +01:00
parent 3f0b94d2fc
commit 35b16bfc49
70 changed files with 1613 additions and 122336 deletions

9
src/core/compat/assert.h Normal file
View File

@@ -0,0 +1,9 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#define assert(x) ((void)0)
#define NDEBUG 1

0
src/core/compat/ctype.h Normal file
View File

0
src/core/compat/fenv.h Normal file
View File

View File

@@ -0,0 +1,27 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"
#define PRIX64 "llX"
#define PRId32 "d"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIdPTR "ld"
#define PRIuPTR "lu"
#define PRIxPTR "lx"
#define PRIXPTR "lX"
#endif

195
src/core/compat/main.c Normal file
View File

@@ -0,0 +1,195 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#define NULL ((void*)0)
// EFI definitions
typedef uint64_t EFI_STATUS;
typedef void* EFI_HANDLE;
#define EFI_SUCCESS 0
typedef struct {
uint64_t signature;
uint32_t revision;
uint32_t headerSize;
uint32_t crc32;
uint32_t reserved;
} EFI_TABLE_HEADER;
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef EFI_STATUS (*EFI_TEXT_STRING)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
uint16_t *String
);
typedef EFI_STATUS (*EFI_TEXT_CLEAR_SCREEN)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
);
typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
void *reset;
EFI_TEXT_STRING OutputString;
void *testString;
void *queryMode;
void *setMode;
void *setAttribute;
EFI_TEXT_CLEAR_SCREEN ClearScreen;
void *setCursorPosition;
void *enableCursor;
void *mode;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef struct EFI_SYSTEM_TABLE {
EFI_TABLE_HEADER hdr;
uint16_t *firmwareVendor;
uint32_t firmwareRevision;
void *consoleInHandle;
void *conIn;
void *consoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
void *standardErrorHandle;
void *stdErr;
void *runtimeServices;
void *bootServices;
uint64_t numberOfTableEntries;
void *configurationTable;
} EFI_SYSTEM_TABLE;
static EFI_SYSTEM_TABLE *gST = NULL;
static void Print(uint16_t *str) {
if (gST && gST->ConOut)
gST->ConOut->OutputString(gST->ConOut, str);
}
static uint16_t *AsciiToUnicode(const char *ascii) {
static uint16_t buffer[1024];
int i;
for (i = 0; ascii[i] && i < 1023; i++) {
buffer[i] = (uint16_t)ascii[i];
}
buffer[i] = 0;
return buffer;
}
// stdio implementation
int printf(const char *format, ...) {
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
Print(AsciiToUnicode(buf));
return ret;
}
int fprintf(FILE *stream, const char *format, ...) {
if (stream != stdout && stream != stderr) return 0;
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
Print(AsciiToUnicode(buf));
return ret;
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
if (stream != stdout && stream != stderr) return 0;
const char *p = ptr;
size_t total = size * nmemb;
char buf[1025];
size_t i = 0;
while (i < total) {
size_t chunk = total - i;
if (chunk > 1024) chunk = 1024;
memcpy(buf, p + i, chunk);
buf[chunk] = 0;
Print(AsciiToUnicode(buf));
i += chunk;
}
return nmemb;
}
int fputc(int c, FILE *stream) {
if (stream != stdout && stream != stderr) return c;
char buf[2] = { (char)c, 0 };
Print(AsciiToUnicode(buf));
return c;
}
int putchar(int c) {
return fputc(c, stdout);
}
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
(void)ImageHandle;
gST = SystemTable;
gST->ConOut->ClearScreen(gST->ConOut);
Print(L"UEFI QuickJS\r\n");
Print(L"============\r\n\r\n");
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
Print(L"Failed to create runtime\r\n");
return EFI_SUCCESS;
}
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
Print(L"Failed to create context\r\n");
JS_FreeRuntime(rt);
return EFI_SUCCESS;
}
Print(L"QuickJS initialized!\r\n\r\n");
// Test Classes
const char *code =
"class Test { "
" constructor(val) { this.val = val; } "
" getVal() { return this.val; } "
"} "
"let t = new Test(42); "
"t.getVal();";
Print(L"Evaluating code...\r\n");
JSValue val = JS_Eval(ctx, code, strlen(code), "<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(val)) {
JSValue ex = JS_GetException(ctx);
const char *str = JS_ToCString(ctx, ex);
if (str) {
printf("Exception: %s\n", str);
JS_FreeCString(ctx, str);
} else {
printf("Exception: [unknown]\n");
}
JS_FreeValue(ctx, ex);
} else {
const char *str = JS_ToCString(ctx, val);
if (str) {
printf("Result: %s\n", str);
JS_FreeCString(ctx, str);
} else {
printf("Result: [unknown]\n");
}
JS_FreeValue(ctx, val);
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
Print(L"\r\nSuccess!\r\n");
Print(L"\r\nPress Ctrl+C...\r\n");
for(;;);
return EFI_SUCCESS;
}

51
src/core/compat/math.h Normal file
View File

@@ -0,0 +1,51 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _MATH_H
#define _MATH_H
#define NAN (__builtin_nan(""))
#define INFINITY (__builtin_inf())
#define signbit(x) __builtin_signbit(x)
double floor(double x);
double ceil(double x);
double fabs(double x);
double modf(double x, double *iptr);
double fmod(double x, double y);
double sqrt(double x);
double pow(double x, double y);
double log(double x);
double exp(double x);
double sin(double x);
double cos(double x);
double tan(double x);
int isnan(double x);
int isinf(double x);
int isfinite(double x);
double trunc(double x);
double fmin(double x, double y);
double fmax(double x, double y);
double hypot(double x, double y);
double acos(double x);
double asin(double x);
double atan(double x);
double atan2(double y, double x);
double cbrt(double x);
double cosh(double x);
double expm1(double x);
double log1p(double x);
double log2(double x);
double log10(double x);
double sinh(double x);
double tanh(double x);
double asinh(double x);
double acosh(double x);
double atanh(double x);
double round(double x);
long int lrint(double x);
#endif

664
src/core/compat/minilibc.c Normal file
View File

@@ -0,0 +1,664 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
extern int printf(const char *format, ...);
// Basic libc stub implementations for Elk
// String functions
void *memset(void *s, int c, size_t n) {
unsigned char *p = s;
while (n--) *p++ = (unsigned char)c;
return s;
}
void *memcpy(void *dest, const void *src, size_t n) {
unsigned char *d = dest;
const unsigned char *s = src;
while (n--) *d++ = *s++;
return dest;
}
void *memmove(void *dest, const void *src, size_t n) {
unsigned char *d = dest;
const unsigned char *s = src;
if (d < s) {
while (n--) *d++ = *s++;
} else {
d += n;
s += n;
while (n--) *--d = *--s;
}
return dest;
}
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
while (n--) {
if (*p1 != *p2) return *p1 - *p2;
p1++;
p2++;
}
return 0;
}
size_t strlen(const char *s) {
size_t len = 0;
while (s[len]) len++;
return len;
}
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
s1++;
s2++;
n--;
}
if (n == 0) return 0;
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
char *strcpy(char *dest, const char *src) {
char *d = dest;
while ((*d++ = *src++));
return dest;
}
char *strncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n && src[i]; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}
// Math functions - basic implementations
double floor(double x) {
if (x >= 0) {
return (double)(int64_t)x;
} else {
int64_t i = (int64_t)x;
return (i == x) ? x : (double)(i - 1);
}
}
double ceil(double x) {
if (x >= 0) {
int64_t i = (int64_t)x;
return (i == x) ? x : (double)(i + 1);
} else {
return (double)(int64_t)x;
}
}
double fabs(double x) {
return x < 0 ? -x : x;
}
double modf(double x, double *iptr) {
*iptr = (double)(int64_t)x;
return x - *iptr;
}
double fmod(double x, double y) {
if (y == 0.0) return 0.0;
return x - floor(x / y) * y;
}
// Simple sqrt using Newton's method
double sqrt(double x) {
if (x < 0) return 0.0;
if (x == 0) return 0.0;
double guess = x / 2.0;
double prev;
int iterations = 10;
while (iterations--) {
prev = guess;
guess = (guess + x / guess) / 2.0;
if (fabs(guess - prev) < 0.0001) break;
}
return guess;
}
double pow(double x, double y) {
// Very basic pow - only handles integer exponents
if (y == 0.0) return 1.0;
if (y < 0.0) return 1.0 / pow(x, -y);
double result = 1.0;
int64_t exp = (int64_t)y;
while (exp--) result *= x;
return result;
}
double log(double x) {
// Simplified log (not accurate, just enough for Elk)
if (x <= 0) return 0.0;
return 0.0; // Stub
}
double exp(double x) {
// Simplified exp
(void)x;
return 1.0; // Stub
}
double sin(double x) {
(void)x;
return 0.0; // Stub
}
double cos(double x) {
(void)x;
return 1.0; // Stub
}
double tan(double x) {
(void)x;
return 0.0; // Stub
}
int isnan(double x) {
return x != x;
}
int isinf(double x) {
return x == __builtin_inf() || x == -__builtin_inf();
}
int isfinite(double x) {
return !isnan(x) && !isinf(x);
}
// Stdlib functions
double strtod(const char *str, char **endptr) {
double result = 0.0;
double sign = 1.0;
double scale = 0.1;
int decimal = 0;
while (*str == ' ' || *str == '\t') str++;
if (*str == '-') {
sign = -1.0;
str++;
} else if (*str == '+') {
str++;
}
while (*str) {
if (*str >= '0' && *str <= '9') {
if (decimal) {
result += (*str - '0') * scale;
scale *= 0.1;
} else {
result = result * 10.0 + (*str - '0');
}
} else if (*str == '.' && !decimal) {
decimal = 1;
} else {
break;
}
str++;
}
if (endptr) *endptr = (char *)str;
return result * sign;
}
long strtol(const char *str, char **endptr, int base) {
long result = 0;
int sign = 1;
while (*str == ' ') str++;
if (*str == '-') {
sign = -1;
str++;
}
while (*str >= '0' && *str <= '9') {
result = result * base + (*str - '0');
str++;
}
if (endptr) *endptr = (char *)str;
return result * sign;
}
#define HEAP_SIZE (8 * 1024 * 1024)
static unsigned char heap[HEAP_SIZE];
static size_t heap_pos = 0;
void *malloc(size_t size) {
size = (size + 7) & ~7;
size_t total = size + 8;
if (heap_pos + total > HEAP_SIZE) {
printf("malloc failed: OOM\n");
return (void*)0;
}
*(size_t*)&heap[heap_pos] = size;
void *ptr = &heap[heap_pos + 8];
heap_pos += total;
return ptr;
}
void free(void *ptr) {
(void)ptr;
}
void *realloc(void *ptr, size_t size) {
if (!ptr) return malloc(size);
size_t *p_size = (size_t*)((char*)ptr - 8);
size_t old_size = *p_size;
if (size <= old_size) return ptr;
void *new_ptr = malloc(size);
if (!new_ptr) return (void*)0;
memcpy(new_ptr, ptr, old_size);
return new_ptr;
}
void *calloc(size_t nmemb, size_t size) {
size_t total = nmemb * size;
void *ptr = malloc(total);
if (ptr) memset(ptr, 0, total);
return ptr;
}
void abort(void) {
printf("ABORT called!\n");
while(1);
}
// stdio functions
int vsnprintf(char *str, size_t size, const char *format, __builtin_va_list ap) {
size_t i = 0;
const char *p = format;
while (*p && i < size - 1) {
if (*p != '%') {
str[i++] = *p++;
continue;
}
p++; // Skip '%'
// Parse flags, width, precision, length modifiers
int precision = -1;
// Flags (ignored for now)
while (*p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '0') p++;
// Width
if (*p == '*') {
__builtin_va_arg(ap, int); // Consume width
p++;
} else {
while (*p >= '0' && *p <= '9') p++;
}
// Precision
if (*p == '.') {
p++;
if (*p == '*') {
precision = __builtin_va_arg(ap, int);
p++;
} else {
int val = 0;
while (*p >= '0' && *p <= '9') {
val = val * 10 + (*p - '0');
p++;
}
precision = val;
}
}
// Length modifiers (ignored)
while (*p == 'h' || *p == 'l' || *p == 'L' || *p == 'z' || *p == 't') p++;
if (*p == 'd' || *p == 'i') {
int val = __builtin_va_arg(ap, int);
char buf[32];
int pos = 0;
int neg = 0;
if (val < 0) { neg = 1; val = -val; }
if (val == 0) buf[pos++] = '0';
while (val) {
buf[pos++] = '0' + (val % 10);
val /= 10;
}
if (neg) buf[pos++] = '-';
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
} else if (*p == 'u') {
unsigned int val = __builtin_va_arg(ap, unsigned int);
char buf[32];
int pos = 0;
if (val == 0) buf[pos++] = '0';
while (val) {
buf[pos++] = '0' + (val % 10);
val /= 10;
}
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
} else if (*p == 's') {
const char *s = __builtin_va_arg(ap, const char *);
if (!s) s = "(null)";
size_t len = 0;
const char *tmp = s;
while (*tmp++) len++;
if (precision >= 0 && len > (size_t)precision) len = (size_t)precision;
size_t k = 0;
while (k < len && i < size - 1) str[i++] = s[k++];
} else if (*p == 'c') {
char c = (char)__builtin_va_arg(ap, int);
if (i < size - 1) str[i++] = c;
} else if (*p == 'g' || *p == 'f') {
// Basic double support
double val = __builtin_va_arg(ap, double);
int ival = (int)val;
// Print integer part
char buf[32];
int pos = 0;
int neg = 0;
if (val < 0) { neg = 1; val = -val; ival = -ival; }
if (ival == 0) buf[pos++] = '0';
int temp = ival;
while (temp) {
buf[pos++] = '0' + (temp % 10);
temp /= 10;
}
if (neg) buf[pos++] = '-';
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
// Simple decimal part (up to 4 digits)
val -= (int)val;
if (val > 0.0001) {
if (i < size - 1) str[i++] = '.';
for (int k=0; k<4 && val > 0.0001 && i < size-1; k++) {
val *= 10;
int digit = (int)val;
str[i++] = '0' + digit;
val -= digit;
}
}
} else {
if (i < size - 1) str[i++] = *p;
}
p++;
}
str[i] = '\0';
return i;
}
int snprintf(char *str, size_t size, const char *format, ...) {
__builtin_va_list ap;
__builtin_va_start(ap, format);
int ret = vsnprintf(str, size, format, ap);
__builtin_va_end(ap);
return ret;
}
// Compiler intrinsics for Windows target
void __chkstk(void) {
// Stack checking - not needed for UEFI
}
int _fltused = 0; // Floating point used marker
char *strchr(const char *s, int c) {
while (*s != (char)c) {
if (!*s++) {
return (void*)0;
}
}
return (char *)s;
}
double trunc(double x) {
return (x > 0) ? floor(x) : ceil(x);
}
double fmin(double x, double y) {
return (x < y) ? x : y;
}
double fmax(double x, double y) {
return (x > y) ? x : y;
}
double hypot(double x, double y) {
return sqrt(x*x + y*y);
}
double acos(double x) { (void)x; return 0.0; }
double asin(double x) { (void)x; return 0.0; }
double atan(double x) { (void)x; return 0.0; }
double atan2(double y, double x) { (void)y; (void)x; return 0.0; }
double cbrt(double x) { (void)x; return 0.0; }
double cosh(double x) { (void)x; return 0.0; }
double expm1(double x) { (void)x; return 0.0; }
double log1p(double x) { (void)x; return 0.0; }
double log2(double x) { (void)x; return 0.0; }
double log10(double x) { (void)x; return 0.0; }
double sinh(double x) { (void)x; return 0.0; }
double tanh(double x) { (void)x; return 0.0; }
double asinh(double x) { (void)x; return 0.0; }
double acosh(double x) { (void)x; return 0.0; }
double atanh(double x) { (void)x; return 0.0; }
double round(double x) {
return (x >= 0.0) ? floor(x + 0.5) : ceil(x - 0.5);
}
long int lrint(double x) {
return (long int)round(x);
}
size_t _msize(void *ptr) {
if (!ptr) return 0;
return *(size_t*)((char*)ptr - 8);
}
int fesetround(int round) { (void)round; return 0; }
int fegetround(void) { return 0; }
int errno = 0;
#include "time.h"
#include "sys/time.h"
time_t time(time_t *t) {
if (t) *t = 0;
return 0;
}
static struct tm tm_buf;
struct tm *gmtime(const time_t *timep) {
(void)timep;
// Stub: return 1970-01-01
tm_buf.tm_year = 70;
tm_buf.tm_mon = 0;
tm_buf.tm_mday = 1;
return &tm_buf;
}
struct tm *localtime(const time_t *timep) {
return gmtime(timep);
}
time_t mktime(struct tm *tm) {
(void)tm;
return 0;
}
int gettimeofday(struct timeval *tv, struct timezone *tz) {
if (tv) {
tv->tv_sec = 0;
tv->tv_usec = 0;
}
return 0;
}
void *memchr(const void *s, int c, size_t n) {
const unsigned char *p = s;
while (n--) {
if (*p == (unsigned char)c) return (void *)p;
p++;
}
return (void*)0;
}
char *strcat(char *dest, const char *src) {
char *d = dest;
while (*d) d++;
while ((*d++ = *src++));
return dest;
}
char *strncat(char *dest, const char *src, size_t n) {
char *d = dest;
while (*d) d++;
while (n-- && *src) *d++ = *src++;
*d = 0;
return dest;
}
char *strstr(const char *haystack, const char *needle) {
size_t len = strlen(needle);
if (len == 0) return (char *)haystack;
while (*haystack) {
if (!memcmp(haystack, needle, len)) return (char *)haystack;
haystack++;
}
return (void*)0;
}
char *strdup(const char *s) {
size_t len = strlen(s) + 1;
char *new = malloc(len);
if (new) memcpy(new, s, len);
return new;
}
char *strrchr(const char *s, int c) {
const char *found = (void*)0;
while (*s) {
if (*s == (char)c) found = s;
s++;
}
if (*s == (char)c) found = s;
return (char *)found;
}
int abs(int j) {
return (j < 0) ? -j : j;
}
int isdigit(int c) {
return (c >= '0' && c <= '9');
}
int isspace(int c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r');
}
int isupper(int c) {
return (c >= 'A' && c <= 'Z');
}
int islower(int c) {
return (c >= 'a' && c <= 'z');
}
int isalpha(int c) {
return isupper(c) || islower(c);
}
int isalnum(int c) {
return isalpha(c) || isdigit(c);
}
int tolower(int c) {
return isupper(c) ? c + 32 : c;
}
int toupper(int c) {
return islower(c) ? c - 32 : c;
}
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
// Simple bubble sort for now
if (nmemb < 2 || size == 0) return;
char *b = (char *)base;
// Byte-by-byte swap to avoid malloc
for (size_t i = 0; i < nmemb - 1; i++) {
for (size_t j = 0; j < nmemb - i - 1; j++) {
if (compar(b + j * size, b + (j + 1) * size) > 0) {
char *p1 = b + j * size;
char *p2 = b + (j + 1) * size;
for (size_t k = 0; k < size; k++) {
char t = p1[k];
p1[k] = p2[k];
p2[k] = t;
}
}
}
}
}
#include "setjmp.h"
int setjmp(jmp_buf env) {
(void)env;
return 0;
}
void longjmp(jmp_buf env, int val) {
(void)env; (void)val;
printf("longjmp called!\n");
abort();
}

18
src/core/compat/setjmp.h Normal file
View File

@@ -0,0 +1,18 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _SETJMP_H
#define _SETJMP_H
#include <stdint.h>
// x86_64 jmp_buf: rbx, rbp, r12, r13, r14, r15, rsp, rip
typedef uint64_t jmp_buf[8];
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
#endif

12
src/core/compat/stdarg.h Normal file
View File

@@ -0,0 +1,12 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)

23
src/core/compat/stdio.h Normal file
View File

@@ -0,0 +1,23 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#include <stdarg.h>
#include <stddef.h>
typedef struct FILE FILE;
#define stdout ((FILE*)1)
#define stderr ((FILE*)2)
#define stdin ((FILE*)0)
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int fputc(int c, FILE *stream);
int putchar(int c);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

20
src/core/compat/stdlib.h Normal file
View File

@@ -0,0 +1,20 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#include <stddef.h>
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
double strtod(const char *str, char **endptr);
long strtol(const char *str, char **endptr, int base);
void abort(void);
#define alloca __builtin_alloca
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
int abs(int j);
size_t _msize(void *ptr);

29
src/core/compat/string.h Normal file
View File

@@ -0,0 +1,29 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _STRING_H
#define _STRING_H
#include <stddef.h>
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strstr(const char *haystack, const char *needle);
char *strdup(const char *s);
void *memchr(const void *s, int c, size_t n);
#endif

View File

@@ -0,0 +1,24 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
#include "time.h"
struct timeval {
long tv_sec;
long tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif

31
src/core/compat/time.h Normal file
View File

@@ -0,0 +1,31 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _TIME_H
#define _TIME_H
#include <stddef.h>
typedef long time_t;
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
time_t time(time_t *t);
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
time_t mktime(struct tm *tm);
#endif

56
src/core/efi.h Normal file
View File

@@ -0,0 +1,56 @@
#ifndef EFI_H
#define EFI_H
#define NULL ((void*)0)
// EFI definitions
typedef uint64_t EFI_STATUS;
typedef void* EFI_HANDLE;
#define EFI_SUCCESS 0
typedef struct {
uint64_t signature;
uint32_t revision;
uint32_t headerSize;
uint32_t crc32;
uint32_t reserved;
} EFI_TABLE_HEADER;
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef EFI_STATUS (*EFI_TEXT_STRING)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
uint16_t *String
);
typedef EFI_STATUS (*EFI_TEXT_CLEAR_SCREEN)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
);
typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
void *reset;
EFI_TEXT_STRING OutputString;
void *testString;
void *queryMode;
void *setMode;
void *setAttribute;
EFI_TEXT_CLEAR_SCREEN ClearScreen;
void *setCursorPosition;
void *enableCursor;
void *mode;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef struct EFI_SYSTEM_TABLE {
EFI_TABLE_HEADER hdr;
uint16_t *firmwareVendor;
uint32_t firmwareRevision;
void *consoleInHandle;
void *conIn;
void *consoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
void *standardErrorHandle;
void *stdErr;
void *runtimeServices;
void *bootServices;
uint64_t numberOfTableEntries;
void *configurationTable;
} EFI_SYSTEM_TABLE;
#endif

163
src/core/main.c Normal file
View File

@@ -0,0 +1,163 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#include "efi.h"
#include "util.h"
static EFI_SYSTEM_TABLE *gST = NULL;
void print(uint16_t *str) {
if (gST && gST->ConOut)
gST->ConOut->OutputString(gST->ConOut, str);
}
int printf(const char *format, ...) {
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
print(AsciiToUnicode(buf));
return ret;
}
int fprintf(FILE *stream, const char *format, ...) {
if (stream != stdout && stream != stderr) return 0;
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
print(AsciiToUnicode(buf));
return ret;
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
if (stream != stdout && stream != stderr) return 0;
const char *p = ptr;
size_t total = size * nmemb;
char buf[1025];
size_t i = 0;
while (i < total) {
size_t chunk = total - i;
if (chunk > 1024) chunk = 1024;
memcpy(buf, p + i, chunk);
buf[chunk] = 0;
print(AsciiToUnicode(buf));
i += chunk;
}
return nmemb;
}
int fputc(int c, FILE *stream) {
if (stream != stdout && stream != stderr) return c;
char buf[2] = { (char)c, 0 };
print(AsciiToUnicode(buf));
return c;
}
int putchar(int c) {
return fputc(c, stdout);
}
// ------------------------------- Kernel C TS bindings -------------------------------
JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
const char *str = JS_ToCString(ctx, argv[0]);
if (!str) return JS_EXCEPTION;
print(AsciiToUnicode(str));
print(L"\r\n");
JS_FreeCString(ctx, str);
return JS_UNDEFINED;
}
void initKC(JSContext *ctx) {
JSValue global = JS_GetGlobalObject(ctx);
JSValue kc = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, global, "kc", kc);
JS_SetPropertyStr(ctx, kc, "println", JS_NewCFunction(ctx, jsKCPrintln, "println", 1));
JS_FreeValue(ctx, global);
}
// ------------------------------------- EFI main -------------------------------------
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
(void)ImageHandle;
gST = SystemTable;
gST->ConOut->ClearScreen(gST->ConOut);
print(L"Booting LintsOS...\r\n");
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
print(L"!!! Kernel panic: Failed to create runtime !!!\r\n");
return EFI_SUCCESS;
}
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
print(L"!!! Kernel panic: Failed to create context !!!\r\n");
JS_FreeRuntime(rt);
return EFI_SUCCESS;
}
initKC(ctx);
const char *code =
"kc.println(\"Hello from Kernel C!\")";
JSValue val = JS_Eval(ctx, code, strlen(code), "<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(val)) {
JSValue ex = JS_GetException(ctx);
const char *str = JS_ToCString(ctx, ex);
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else {
printf("!!! Kernel panic: [unknown] !!!\n");
}
JS_FreeValue(ctx, ex);
} else {
const char *str = JS_ToCString(ctx, val);
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else {
printf("!!! Kernel panic: [unknown] !!!\n");
}
JS_FreeValue(ctx, val);
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
for(;;);
return EFI_SUCCESS;
}

32
src/core/util.c Normal file
View File

@@ -0,0 +1,32 @@
#include "util.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#include "efi.h"
void halt() {
for(;;);
}
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
uint16_t *AsciiToUnicode(const char *ascii) {
static uint16_t buffer[1024];
int i;
for (i = 0; ascii[i] && i < 1023; i++) {
buffer[i] = (uint16_t)ascii[i];
}
buffer[i] = 0;
return buffer;
}

13
src/core/util.h Normal file
View File

@@ -0,0 +1,13 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#ifndef UTIL_H
#define UTIL_H
void halt();
uint16_t *AsciiToUnicode(const char *ascii);
#endif