From fcefe9f827b9fc6bc735ac8d44dd378a8588d96c Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Mon, 24 Nov 2025 22:59:39 +0100 Subject: [PATCH] Porting to WASM --- build.bat | 31 ++++++ build_web.bat | 13 +++ build_web.sh | 64 +++++++++++ data/shell.html | 42 ++++++++ src/basic/wasm.cpp | 262 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 412 insertions(+) create mode 100644 build.bat create mode 100644 build_web.bat create mode 100644 build_web.sh create mode 100644 data/shell.html create mode 100644 src/basic/wasm.cpp diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..5330154 --- /dev/null +++ b/build.bat @@ -0,0 +1,31 @@ +@echo off + +mkdir build +cd build + +if "%1"=="release" ( + set profile_flags=-DDEBUG_BUILD=0 -O2 +) else ( + set profile_flags=-DDEBUG_BUILD=1 +) + +if not exist "lbaselib.obj" ( + cl -Zi -nologo -I../src/external/lua/src -I../src/external/glad ../src/external/lua/src/lbaselib.c ../src/external/lua/src/lctype.c ../src/external/lua/src/ldo.c ../src/external/lua/src/lgc.c ../src/external/lua/src/liolib.c ../src/external/lua/src/lmem.c ../src/external/lua/src/lopcodes.c ../src/external/lua/src/lstate.c ../src/external/lua/src/ltable.c ../src/external/lua/src/lundump.c ../src/external/lua/src/lzio.c ../src/external/lua/src/lapi.c ../src/external/lua/src/lcode.c ../src/external/lua/src/ldblib.c ../src/external/lua/src/ldump.c ../src/external/lua/src/llex.c ../src/external/lua/src/loadlib.c ../src/external/lua/src/loslib.c ../src/external/lua/src/lstring.c ../src/external/lua/src/ltablib.c ../src/external/lua/src/lutf8lib.c ../src/external/lua/src/lauxlib.c ../src/external/lua/src/lcorolib.c ../src/external/lua/src/ldebug.c ../src/external/lua/src/lfunc.c ../src/external/lua/src/linit.c ../src/external/lua/src/lmathlib.c ../src/external/lua/src/lobject.c ../src/external/lua/src/lparser.c ../src/external/lua/src/lstrlib.c ../src/external/lua/src/ltm.c ../src/external/lua/src/lvm.c ../src/external/glad/glad.c -c +) + +if not exist "metaprogram.exe" ( + cl /WX /W3 /wd4200 /diagnostics:column -FC -Zi -nologo -Fe:metaprogram.exe -I../src ../src/metaprogram/metaprogram.cpp ../src/basic/win32.cpp +) +metaprogram.exe + + +set sdl=../src/external/SDL/win32-static/SDL3-static.lib ../src/external/SDL/win32-static/SDL_uclibc.lib +cl /EHsc- /MD /Zi /FC /nologo /WX /W3 /wd4200 /diagnostics:column %profile_flags% ../src/text_editor/text_editor.cpp ../src/basic/win32.cpp -Fe:te.exe -I../src/external/SDL/include -I../src/external/lua/src -I../src/external/glad -I../src/ lbaselib.obj lctype.obj ldo.obj lgc.obj liolib.obj lmem.obj lopcodes.obj lstate.obj ltable.obj lundump.obj lzio.obj lapi.obj lcode.obj ldblib.obj ldump.obj llex.obj loadlib.obj loslib.obj lstring.obj ltablib.obj lutf8lib.obj lauxlib.obj lcorolib.obj ldebug.obj lfunc.obj linit.obj lmathlib.obj lobject.obj lparser.obj lstrlib.obj ltm.obj lvm.obj glad.obj kernel32.lib gdi32.lib user32.lib Imm32.lib ole32.lib Shell32.lib OleAut32.lib Cfgmgr32.lib Setupapi.lib Advapi32.lib version.lib winmm.lib %sdl% -link /SUBSYSTEM:WINDOWS /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRTD + +if "%1"=="release" ( + copy te.exe ..\data\te.exe + echo written ..\data\te.exe +) else ( + copy te.exe ..\data\te_debug.exe + echo written ..\data\te_debug.exe +) diff --git a/build_web.bat b/build_web.bat new file mode 100644 index 0000000..70bc460 --- /dev/null +++ b/build_web.bat @@ -0,0 +1,13 @@ +@echo off + +set incs=-Isrc/external/SDL/include -Isrc/external/lua/src -Isrc/external/glad -Lsrc/external/SDL/build_web -Isrc +set wasmflags=-gsource-map -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb -msimd128 -sTOTAL_STACK=5MB -sINITIAL_MEMORY=256mb -sUSE_WEBGL2 -sFULL_ES3=1 -sASYNCIFY -sASSERTIONS=2 +set flags=-Wno-writable-strings -nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths -g -DDEBUG_BUILD=1 + +mkdir build +cd build +clang ../src/metaprogram/metaprogram.cpp ../src/basic/win32.cpp -o metaprogram.exe %flags% -I../src +metaprogram.exe +cd .. + +emcc -o text_editor.html --shell-file=data/shell.html %flags% %incs% %wasmflags% -lm -lSDL3 src/text_editor/text_editor.cpp src/basic/wasm.cpp src/external/lua/src/lbaselib.c src/external/lua/src/lctype.c src/external/lua/src/ldo.c src/external/lua/src/lgc.c src/external/lua/src/liolib.c src/external/lua/src/lmem.c src/external/lua/src/lopcodes.c src/external/lua/src/lstate.c src/external/lua/src/ltable.c src/external/lua/src/lundump.c src/external/lua/src/lzio.c src/external/lua/src/lapi.c src/external/lua/src/lcode.c src/external/lua/src/ldblib.c src/external/lua/src/ldump.c src/external/lua/src/llex.c src/external/lua/src/loadlib.c src/external/lua/src/loslib.c src/external/lua/src/lstring.c src/external/lua/src/ltablib.c src/external/lua/src/lutf8lib.c src/external/lua/src/lauxlib.c src/external/lua/src/lcorolib.c src/external/lua/src/ldebug.c src/external/lua/src/lfunc.c src/external/lua/src/linit.c src/external/lua/src/lmathlib.c src/external/lua/src/lobject.c src/external/lua/src/lparser.c src/external/lua/src/lstrlib.c src/external/lua/src/ltm.c src/external/lua/src/lvm.c src/external/glad/glad.c diff --git a/build_web.sh b/build_web.sh new file mode 100644 index 0000000..c9c3118 --- /dev/null +++ b/build_web.sh @@ -0,0 +1,64 @@ +#!/usr/bin/bash + +mkdir build +cd build + +if [ ! -f "metaprogram.exe" ]; then + clang ../src/metaprogram/metaprogram.cpp ../src/basic/unix.cpp -o metaprogram.exe \ + -nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths -g \ + -Wno-writable-strings \ + -I../src +fi +./metaprogram.exe + +emcc -o ../text_editor.html \ + -nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths -g -gsource-map \ + --shell-file=../data/shell.html\ + $profile_flags \ + -Wno-writable-strings \ + -I../src/external/SDL/include \ + -I../src/external/lua/src \ + -I../src/external/glad \ + -I../src/ \ + -L../src/external/SDL/build_web \ + -lm \ + -lSDL3 \ + -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -msimd128 -s TOTAL_STACK=5MB -s INITIAL_MEMORY=256mb \ + ../src/text_editor/text_editor.cpp \ + ../src/basic/unix.cpp \ + ../src/external/lua/src/lbaselib.c \ + ../src/external/lua/src/lctype.c \ + ../src/external/lua/src/ldo.c \ + ../src/external/lua/src/lgc.c \ + ../src/external/lua/src/liolib.c \ + ../src/external/lua/src/lmem.c \ + ../src/external/lua/src/lopcodes.c \ + ../src/external/lua/src/lstate.c \ + ../src/external/lua/src/ltable.c \ + ../src/external/lua/src/lundump.c \ + ../src/external/lua/src/lzio.c \ + ../src/external/lua/src/lapi.c \ + ../src/external/lua/src/lcode.c \ + ../src/external/lua/src/ldblib.c \ + ../src/external/lua/src/ldump.c \ + ../src/external/lua/src/llex.c \ + ../src/external/lua/src/loadlib.c \ + ../src/external/lua/src/loslib.c \ + ../src/external/lua/src/lstring.c \ + ../src/external/lua/src/ltablib.c \ + ../src/external/lua/src/lutf8lib.c \ + ../src/external/lua/src/lauxlib.c \ + ../src/external/lua/src/lcorolib.c \ + ../src/external/lua/src/ldebug.c \ + ../src/external/lua/src/lfunc.c \ + ../src/external/lua/src/linit.c \ + ../src/external/lua/src/lmathlib.c \ + ../src/external/lua/src/lobject.c \ + ../src/external/lua/src/lparser.c \ + ../src/external/lua/src/lstrlib.c \ + ../src/external/lua/src/ltm.c \ + ../src/external/lua/src/lvm.c \ + ../src/external/glad/glad.c \ + + +cd .. \ No newline at end of file diff --git a/data/shell.html b/data/shell.html new file mode 100644 index 0000000..bf2fa9b --- /dev/null +++ b/data/shell.html @@ -0,0 +1,42 @@ + + + + + + Emscripten-Generated Code + + + + + + {{{ SCRIPT }}} + + \ No newline at end of file diff --git a/src/basic/wasm.cpp b/src/basic/wasm.cpp new file mode 100644 index 0000000..0c38841 --- /dev/null +++ b/src/basic/wasm.cpp @@ -0,0 +1,262 @@ +#include "filesystem.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define PATH_MAX 1024 + +EM_JS(void, JS_Breakpoint, (), { + debugger; +}) + +void (*Error)(const char *, ...); + +void *VReserve(size_t size) { + InvalidCodepath(); + return NULL; +} + +bool VCommit(void *p, size_t size) { + InvalidCodepath(); + return false; +} + +bool VRelease(void *p, size_t size) { + InvalidCodepath(); + return false; +} + +bool VDecommit(void *p, size_t size) { + InvalidCodepath(); + return false; +} + +void InitOS(void (*error_proc)(const char *, ...)) { + Error = error_proc; +} + +String ReadFile(Allocator al, String path) { + Scratch scratch(al); + String null_term = Copy(scratch, path); + String result = {}; + FILE *f = fopen(null_term.data, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + result.len = ftell(f); + fseek(f, 0, SEEK_SET); + + result.data = (char *)AllocSize(al, result.len + 1); + fread(result.data, result.len, 1, f); + result.data[result.len] = 0; + + fclose(f); + } + return result; +} + +bool WriteFile(String path, String data) { + Scratch scratch; + String null_term = Copy(scratch, path); + bool result = false; + FILE *f = fopen((const char *)null_term.data, "w"); + if (f) { + size_t written = fwrite(data.data, 1, data.len, f); + if (written == data.len) { + result = true; + } + fclose(f); + } + return result; +} + +bool DeleteFile(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + int result = unlink(null_term.data); + return result == 0; +} + +MakeDirResult MakeDir(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + int error = mkdir(null_term.data, 0755); + MakeDirResult result = MakeDirResult_Success; + if (error != 0) { + result = MakeDirResult_ErrorOther; + if (errno == EEXIST) result = MakeDirResult_Exists; + } + return result; +} + +int64_t GetFileModTime(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + struct stat attrib = {}; + stat(null_term.data, &attrib); + struct timespec ts = attrib.st_mtim; + int64_t result = (((int64_t)ts.tv_sec) * 1000000ll) + ((int64_t)ts.tv_nsec) / 1000ll; + return result; +} + +String GetAbsolutePath(Allocator al, String path) { + return path; +} + +bool FileExists(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + bool result = false; + if (access((char *)null_term.data, F_OK) == 0) { + result = true; + } + return result; +} + +bool IsDir(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + struct stat s; + if (stat(null_term.data, &s) != 0) + return false; + return S_ISDIR(s.st_mode); +} + +bool IsFile(String path) { + Scratch scratch; + String null_term = Copy(scratch, path); + struct stat s; + if (stat(null_term.data, &s) != 0) + return false; + return S_ISREG(s.st_mode); +} + +bool IsAbsolute(String path) { + bool result = path.len && path.data[0] == '/'; + return result; +} + +String GetWorkingDir(Allocator al) { + char *buffer = AllocArray(al, char, PATH_MAX); + char *cwd = getcwd(buffer, PATH_MAX); + return cwd; +} + +String GetExePath(Allocator al) { + return "/text_editor"; +} + +String GetExeDir(Allocator al) { + Scratch scratch(al); + String exe_path = GetExePath(scratch); + String dir = ChopLastSlash(exe_path); + String result = Copy(al, dir); + return result; +} + +double get_time_in_micros(void) { + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); + return (((double)spec.tv_sec) * 1000000) + (((double)spec.tv_nsec) / 1000); +} + +bool IsValid(const FileIter &it) { + return it.is_valid; +} + +void Advance(FileIter *it) { + struct dirent *file = NULL; + while ((file = readdir((DIR *)it->dir)) != NULL) { + if (file->d_name[0] == '.' && file->d_name[1] == '.' && file->d_name[2] == 0) { + continue; + } + if (file->d_name[0] == '.' && file->d_name[1] == 0) { + continue; + } + + it->is_directory = file->d_type == DT_DIR; + it->filename = Copy(it->allocator, file->d_name); + + const char *dir_char_ending = it->is_directory ? "/" : ""; + const char *separator = it->path.data[it->path.len - 1] == '/' ? "" : "/"; + it->relative_path = Format(it->allocator, "%.*s%s%s%s", FmtString(it->path), separator, file->d_name, dir_char_ending); + it->absolute_path = GetAbsolutePath(it->allocator, it->relative_path); + if (it->is_directory) it->absolute_path = Format(it->allocator, "%.*s/", FmtString(it->absolute_path)); + it->is_valid = true; + return; + } + it->is_valid = false; + closedir((DIR *)it->dir); +} + +FileIter IterateFiles(Allocator alo, String path) { + FileIter it = {}; + it.allocator = alo; + it.path = path; + Scratch scratch(alo); + String null_term = Copy(scratch, path); + it.dir = (void *)opendir((char *)null_term.data); + if (it.dir) { + Advance(&it); + } + return it; +} + +Array SplitCommand(Allocator allocator, String command_line) { + Array cmd = {allocator}; + + String curr = {}; + for (int i = 0; i < command_line.len; i += 1) { + if (command_line.data[i] == ' ') { + if (curr.len > 0) { + Add(&cmd, Copy(allocator, curr).data); + curr = {}; + } + continue; + } + if (curr.len == 0) { + curr.data = command_line.data + i; + } + curr.len += 1; + } + + if (curr.len > 0) { + Add(&cmd, Copy(allocator, curr).data); + } + + return cmd; +} + +Process SpawnProcess(String command_line, String working_dir, String write_stdin, Array enviroment) { + return {}; +} + +bool IsValid(Process *process) { + return false; +} + +void KillProcess(Process *process) { + +} + +String PollStdout(Allocator allocator, Process *process, bool force_read) { + return {}; +} + +void WriteStdin(Process *process, String string) { + return; +} + +void CloseStdin(Process *process) { + return; +}