commit d192cfac7a59dbc53d78436124ca37730138d57c Author: Starbeamrainbowlabs Date: Thu Dec 12 03:40:41 2024 +0000 Initial commit Teh goal: Get OSFS working in the browser! Teh progress: It compiles! .....but we don't have malloc(), and we get some undefined synbol errors: wasm-ld-18: error: /tmp/wrapper-0965f8.o: undefined symbol: malloc(unsigned long) wasm-ld-18: error: /tmp/wrapper-0965f8.o: undefined symbol: free(void*) wasm-ld-18: error: /tmp/wrapper-0965f8.o: undefined symbol: malloc(unsigned long) ....these are indicative of a type error I think diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c20ac70 --- /dev/null +++ b/.gitignore @@ -0,0 +1,235 @@ + +src/wasm/bin + +# Created by https://www.toptal.com/developers/gitignore/api/git,node,c,c++ +# Edit at https://www.toptal.com/developers/gitignore?templates=git,node,c,c++ + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### C++ ### +# Prerequisites + +# Compiled Object files +*.slo + +# Precompiled Headers + +# Compiled Dynamic libraries + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai + +# Executables + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/git,node,c,c++ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b4dbb4c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "src/wasm/walloc"] + path = src/wasm/walloc + url = https://github.com/wingo/walloc.git +[submodule "src/wasm/OSFS"] + path = src/wasm/OSFS + url = https://github.com/charlesbaynham/OSFS.git +[submodule "src/lantern-build-engine"] + path = src/lantern-build-engine + url = https://gitlab.com/sbrl/lantern-build-engine.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/index.mjs b/src/index.mjs new file mode 100644 index 0000000..e69de29 diff --git a/src/lantern-build-engine b/src/lantern-build-engine new file mode 160000 index 0000000..094e175 --- /dev/null +++ b/src/lantern-build-engine @@ -0,0 +1 @@ +Subproject commit 094e175740cc6ebc10dd788a60af60e19407d641 diff --git a/src/wasm/OSFS b/src/wasm/OSFS new file mode 160000 index 0000000..e2031f1 --- /dev/null +++ b/src/wasm/OSFS @@ -0,0 +1 @@ +Subproject commit e2031f1d304e2d9c0de4a4d921ea339078db51b8 diff --git a/src/wasm/compile-wasm.sh b/src/wasm/compile-wasm.sh new file mode 100755 index 0000000..12b5a7c --- /dev/null +++ b/src/wasm/compile-wasm.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# Make sure the current directory is the location of this script to simplify matters +cd "$(dirname "$(readlink -f "$0")")" || { echo "Error: Failed to cd to script directory" >&2; exit 1; }; + +# shellcheck source=../lantern-build-engine/lantern.sh +source "${PWD}/../lantern-build-engine/lantern.sh"; + + +task_begin "Setup"; +subtask_begin "Define directories"; +dirpath_output="${PWD}/bin"; +dirpath_include="${PWD}/include"; +dirpath_walloc="${PWD}/walloc"; +dirpath_osfs="${PWD}/OSFS/src"; +subtask_end 0; + +if [[ ! -d "${dirpath_output}" ]]; then + subtask_begin "Create output directory"; + mkdir "${dirpath_output}"; + subtask_end "${?}"; +fi + +check_command clang true; + + +task_begin "Compile"; + +echo -e ">>> Working directory is ${HC}${PWD}${RS}" >&2; + +execute clang -v -v -v --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry \ + -I"${dirpath_include}" \ + -I "${dirpath_walloc}" \ + -I "${dirpath_osfs}" \ + -o "${dirpath_output}/osfs.wasm" \ + "${dirpath_walloc}/walloc.c" \ + "${dirpath_osfs}/OSFS.cpp" \ + "${dirpath_include}/wrapper.cpp" \ + ; + + +task_end "${?}"; \ No newline at end of file diff --git a/src/wasm/include/Arduino.h b/src/wasm/include/Arduino.h new file mode 100644 index 0000000..a339f0a --- /dev/null +++ b/src/wasm/include/Arduino.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include +// #include + +typedef unsigned char byte; + +/* +To use: + +sudo apt install clang llvm lld + +```bash +git clone repo; +// TODO APPLY PATCH HERE +cd OSFS/src +clang --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry -o osfs.wasm OSFS.cpp +``` + +*/ + + +// strncmp, memset, strncpy ref https://github.com/bezlant/s21_strings + +int strncmp(const char *str1, const char *str2, size_t n); + +void *memset(void *str, int c, size_t n); +char *strncpy(char *dest, const char *src, size_t n); diff --git a/src/wasm/include/walloc.h b/src/wasm/include/walloc.h new file mode 100644 index 0000000..d0b7427 --- /dev/null +++ b/src/wasm/include/walloc.h @@ -0,0 +1,2 @@ +void* malloc(size_t size); +void free(void *ptr); \ No newline at end of file diff --git a/src/wasm/include/wrapper.cpp b/src/wasm/include/wrapper.cpp new file mode 100644 index 0000000..cefc7f0 --- /dev/null +++ b/src/wasm/include/wrapper.cpp @@ -0,0 +1,128 @@ +#include "Arduino.h" +#include "OSFS.h" +#include + +// ------------------------------------------------------------------------- + +// Compatibility defs + +// strncmp, memset, strncpy ref https://github.com/bezlant/s21_strings +int strncmp(const char *str1, const char *str2, size_t n) { + int res = 0; + + if (str1 && str2 && n > 0) { + for (size_t i = 0; i < n; i++) { + if (str1[i] == '\0' || str1[i] != str2[i]) { + res = str1[i] - str2[i]; + break; + } + } + } + + return res; +} +void *memset(void *str, int c, size_t n) { + char *s = (char *)str; + + for (size_t i = 0; i < n; i++) { + s[i] = c; + } + + return str; +} +char *strncpy(char *dest, const char *src, size_t n) { + memset(dest, '\0', n); + + for (size_t i = 0; i < n && src[i]; i++) { + dest[i] = src[i]; + } + + return dest; +} + +// ------------------------------------------------------------------------- + +// OSFS wrappers & defs + +const OSFS::result noerr = OSFS::result::NO_ERROR; +const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND; +OSFS::result result; + +uint16_t OSFS::startOfEEPROM = 1; +uint16_t OSFS::endOfEEPROM = 64; // change w/set_eeprom_size + + +byte* memory = (byte*)malloc((size_t)(64*1024)); // virtual EEPROM, default 64KiB + +void __create_memory(uint32_t size) { + free((void*)memory); + void* memory_raw = malloc((size_t)(size * 1024)); + memory = (byte*)memory_raw; +} + + + + +// ------------------------------------------------------------------------- + +// Error handling + +#define ERROR_OUT_OF_BOUNDS 1 + +int last_error = 0; + +int get_last_error() { + return last_error; +} + +// ------------------------------------------------------------------------- + +// OSFS wrapper API + +/** + * Helper function to set the size of the EEPROM unit to operate on. + * + * @param {uint16_t} size The size of the EEPROM unit, in KiB + * @return void + */ +void set_eeprom_size(uint16_t new_size) { + OSFS::endOfEEPROM = new_size; + __create_memory(new_size); +} + +uint16_t get_eeprom_size() { + return OSFS::endOfEEPROM; +} +uint32_t get_eeprom_size_bytes() { + return OSFS::endOfEEPROM * 1024; +} + + + +void OSFS::readNBytes(uint16_t address, unsigned int num, byte* output) { + // eeprom.read(address, output, num); + last_error = 0; + + if(address < OSFS::startOfEEPROM || address + num > OSFS::endOfEEPROM * 1024) { + last_error = ERROR_OUT_OF_BOUNDS; + return; + } + + for (unsigned int i = 0; i < num; i++) { + output[i] = memory[address + i]; + } + +} +void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte* input) { + // eeprom.write(address, input, num); + last_error = 0; + + if (address < OSFS::startOfEEPROM || address + num > OSFS::endOfEEPROM * 1024) { + last_error = ERROR_OUT_OF_BOUNDS; + return; + } + + for (unsigned int i = 0; i < num; i++) { + memory[address + i] = input[i]; + } +} \ No newline at end of file diff --git a/src/wasm/walloc b/src/wasm/walloc new file mode 160000 index 0000000..a93409f --- /dev/null +++ b/src/wasm/walloc @@ -0,0 +1 @@ +Subproject commit a93409f5ebd49c875514c5fee30d3b151f7b0882