From af147b3cb6c6c7e8b23833203b5a64f7c52ebd61 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Sun, 13 Oct 2024 20:01:18 +0200 Subject: [PATCH] adding test for embed --- depell/src/index.css | 11 ++++++ depell/src/index.js | 39 +++++++++++++------- depell/src/main.rs | 8 +++- depell/wasm-hbc/src/lib.rs | 2 +- lang/README.md | 4 ++ lang/src/codegen.rs | 7 ++-- lang/src/lib.rs | 49 +++++++++++++++++-------- lang/src/son.rs | 4 +- lang/tests/codegen_tests_directives.txt | 12 +++--- lang/tests/codegen_tests_pointers.txt | 27 ++++++++++---- 10 files changed, 113 insertions(+), 50 deletions(-) diff --git a/depell/src/index.css b/depell/src/index.css index 94a75211..c88004a8 100644 --- a/depell/src/index.css +++ b/depell/src/index.css @@ -104,3 +104,14 @@ button { button:hover:not(:active) { background: white; } + +div#code-editor { + display: flex; + position: relative; + + span#code-size { + position: absolute; + right: 2px; + font-size: 12px; + } +} diff --git a/depell/src/index.js b/depell/src/index.js index e906c55c..2cd75fa4 100644 --- a/depell/src/index.js +++ b/depell/src/index.js @@ -40,17 +40,19 @@ function compileCode(instance, code, fuel) { /**@type{WebAssembly.Instance}*/ let fmtInstance; /**@type{Promise}*/ let fmtInstaceFuture; -/** @param {string} code @param {"fmt" | "minify"} action - * @returns {Promise} */ -async function modifyCode(code, action) { +async function getFmtInstance() { fmtInstaceFuture ??= WebAssembly.instantiateStreaming(fetch("/hbfmt.wasm"), {}); - fmtInstance ??= (await fmtInstaceFuture).instance; + return fmtInstance ??= (await fmtInstaceFuture).instance; +} +/** @param {WebAssembly.Instance} instance @param {string} code @param {"fmt" | "minify"} action + * @returns {string | undefined} */ +function modifyCode(instance, code, action) { let { INPUT, INPUT_LEN, OUTPUT, OUTPUT_LEN, memory, fmt, minify - } = fmtInstance.exports; + } = instance.exports; if (!(true && memory instanceof WebAssembly.Memory @@ -71,15 +73,15 @@ async function modifyCode(code, action) { dw.setUint32(INPUT_LEN.value, code.length, true); new Uint8Array(memory.buffer, INPUT.value).set(new TextEncoder().encode(code)); - return runWasmFunction(fmtInstance, action === "fmt" ? fmt : minify) ? - bufToString(memory, OUTPUT, OUTPUT_LEN) : "invalid code"; + return runWasmFunction(instance, action === "fmt" ? fmt : minify) ? + bufToString(memory, OUTPUT, OUTPUT_LEN) : undefined; } /** @param {WebAssembly.Instance} instance @param {CallableFunction} func @param {any[]} args * @returns {boolean} */ function runWasmFunction(instance, func, ...args) { - const prev = performance.now(); + //const prev = performance.now(); const { PANIC_MESSAGE, PANIC_MESSAGE_LEN, memory, stack_pointer } = instance.exports; if (!(true && memory instanceof WebAssembly.Memory @@ -101,7 +103,7 @@ function runWasmFunction(instance, func, ...args) { stack_pointer.value = ptr; return false; } finally { - console.log("compiletion took:", performance.now() - prev); + //console.log("compiletion took:", performance.now() - prev); } } @@ -147,17 +149,22 @@ function wireUp(target) { /** @type {{ [key: string]: (content: string) => Promise | string }} */ const applyFns = { timestamp: (content) => new Date(parseInt(content) * 1000).toLocaleString(), - fmt: (content) => modifyCode(content, "fmt").then(c => c), + fmt: (content) => getFmtInstance().then(i => modifyCode(i, content, "fmt") ?? "invalid code"), }; /** @param {HTMLElement} target */ async function bindCodeEdit(target) { const edit = target.querySelector("#code-edit"); if (!(edit instanceof HTMLTextAreaElement)) return; + const codeSize = target.querySelector("#code-size"); + if (!(codeSize instanceof HTMLSpanElement)) never(); + const MAX_CODE_SIZE = parseInt(codeSize.innerHTML); + if (Number.isNaN(MAX_CODE_SIZE)) never(); const errors = target.querySelector("#compiler-output"); if (!(errors instanceof HTMLPreElement)) never(); const hbc = await getHbcInstance(); + const fmt = await getFmtInstance(); const debounce = 100; let timeout = 0; @@ -166,9 +173,14 @@ async function bindCodeEdit(target) { timeout = setTimeout(() => { const buf = packPosts([ { path: "local.hb", code: edit.value }, - { path: "lam.hb", code: "foo:=10" }, ]); errors.textContent = compileCode(hbc, buf, 1); + const minified_size = modifyCode(fmt, edit.value, "minify")?.length; + if (minified_size) { + codeSize.textContent = (MAX_CODE_SIZE - minified_size) + ""; + const perc = Math.min(100, Math.floor(100 * (minified_size / MAX_CODE_SIZE))); + codeSize.style.color = `color-mix(in srgb, white, var(--error) ${perc}%)`; + } timeout = 0; }, debounce); }); @@ -246,8 +258,9 @@ if (window.location.hostname === 'localhost') { (async function test() { { const code = "main:=fn():void{return}"; - const fmtd = await modifyCode(code, "fmt") ?? never(); - const prev = await modifyCode(fmtd, "minify") ?? never(); + const inst = await getFmtInstance() + const fmtd = modifyCode(inst, code, "fmt") ?? never(); + const prev = modifyCode(inst, fmtd, "minify") ?? never(); if (code != prev) console.error(code, prev); } { diff --git a/depell/src/main.rs b/depell/src/main.rs index 2ef89973..7d147838 100644 --- a/depell/src/main.rs +++ b/depell/src/main.rs @@ -12,7 +12,7 @@ use { const MAX_NAME_LENGTH: usize = 32; const MAX_POSTNAME_LENGTH: usize = 64; -//const MAX_CODE_LENGTH: usize = 1024 * 4; +const MAX_CODE_LENGTH: usize = 1024 * 4; const SESSION_DURATION_SECS: u64 = 60 * 60; type Redirect = AppendHeaders<[(&'static str, &'static str); COUNT]>; @@ -153,7 +153,11 @@ impl Page for Post { - +
+ + MAX_CODE_LENGTH +

             
diff --git a/depell/wasm-hbc/src/lib.rs b/depell/wasm-hbc/src/lib.rs
index 5788f5ed..92a2e0d9 100644
--- a/depell/wasm-hbc/src/lib.rs
+++ b/depell/wasm-hbc/src/lib.rs
@@ -104,5 +104,5 @@ unsafe fn compile_and_run(mut fuel: usize) {
         }
     }
 
-    log::error!("memory consumption: {}b / {}b", ALLOCATOR.used(), ARENA_CAP);
+    //log::error!("memory consumption: {}b / {}b", ALLOCATOR.used(), ARENA_CAP);
 }
diff --git a/lang/README.md b/lang/README.md
index 07189335..c3047810 100644
--- a/lang/README.md
+++ b/lang/README.md
@@ -251,6 +251,7 @@ main := fn(): int {
 	align_of_Type_in_bytes := @alignof(foo.Type)
 	hardcoded_pointer := @as(^u8, @bitcast(10))
 	ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6))
+	embedded_array := @as([u8; 15], @embed("text.txt"))
 	return @inline(foo.foo)
 }
 
@@ -262,6 +263,9 @@ Type := struct {
 }
 
 foo := fn(): int return 0
+
+// in module: text.txt
+arbitrary text
 ```
 
 - `@use()`: imports a module based of string, the string is passed to a loader that can be customized, default loader uses following syntax:
diff --git a/lang/src/codegen.rs b/lang/src/codegen.rs
index 5a1183ef..926f1272 100644
--- a/lang/src/codegen.rs
+++ b/lang/src/codegen.rs
@@ -12,7 +12,7 @@ use {
         TypedReloc, Types, HEADER_SIZE,
     },
     alloc::{boxed::Box, string::String, vec::Vec},
-    core::{fmt::Display, u16},
+    core::fmt::Display,
 };
 
 type Offset = u32;
@@ -2843,8 +2843,9 @@ mod tests {
         _ = log::set_logger(&crate::fs::Logger);
         log::set_max_level(log::LevelFilter::Debug);
 
-        let mut codegen =
-            super::Codegen { files: crate::test_parse_files(ident, input), ..Default::default() };
+        let (files, embeds) = crate::test_parse_files(ident, input);
+        let mut codegen = super::Codegen { files, ..Default::default() };
+        codegen.push_embeds(embeds);
 
         codegen.generate(0);
         let mut out = Vec::new();
diff --git a/lang/src/lib.rs b/lang/src/lib.rs
index 96d197c4..4cda36e5 100644
--- a/lang/src/lib.rs
+++ b/lang/src/lib.rs
@@ -41,7 +41,6 @@ use {
     core::{cell::Cell, ops::Range},
     hashbrown::hash_map,
     hbbytecode as instrs,
-    std::println,
 };
 
 #[macro_use]
@@ -1081,7 +1080,6 @@ impl Types {
         match entry {
             hash_map::RawEntryMut::Occupied(o) => o.get_key_value().0.value,
             hash_map::RawEntryMut::Vacant(v) => {
-                println!("waht");
                 self.ins.ptrs.push(ptr);
                 v.insert(
                     ctx_map::Key {
@@ -1345,7 +1343,7 @@ pub fn run_test(
 }
 
 #[cfg(test)]
-fn test_parse_files(ident: &'static str, input: &'static str) -> Vec {
+fn test_parse_files(ident: &'static str, input: &'static str) -> (Vec, Vec>) {
     use {
         self::parser::FileKind,
         std::{borrow::ToOwned, string::ToString},
@@ -1377,32 +1375,51 @@ fn test_parse_files(ident: &'static str, input: &'static str) -> Vec module_map
             .iter()
             .position(|&(name, _)| name == path)
             .map(|i| i as parser::FileId)
-            .ok_or("Not Found".to_string())
+            .ok_or("Module Not Found".to_string()),
+        FileKind::Embed => embed_map
+            .iter()
+            .position(|&(name, _)| name == path)
+            .map(|i| i as parser::FileId)
+            .ok_or("Embed Not Found".to_string()),
     };
 
     let mut ctx = parser::ParserCtx::default();
-    module_map
-        .iter()
-        .map(|&(path, content)| parser::Ast::new(path, content.to_owned(), &mut ctx, &mut loader))
-        .collect()
+    (
+        module_map
+            .iter()
+            .map(|&(path, content)| {
+                parser::Ast::new(path, content.to_owned(), &mut ctx, &mut loader)
+            })
+            .collect(),
+        embed_map.iter().map(|&(_, content)| content.to_owned().into_bytes()).collect(),
+    )
 }
 
 #[cfg(test)]
diff --git a/lang/src/son.rs b/lang/src/son.rs
index a5c16a3f..e1f4c054 100644
--- a/lang/src/son.rs
+++ b/lang/src/son.rs
@@ -2861,8 +2861,8 @@ mod tests {
         _ = log::set_logger(&crate::fs::Logger);
         log::set_max_level(log::LevelFilter::Info);
 
-        let mut codegen =
-            super::Codegen { files: crate::test_parse_files(ident, input), ..Default::default() };
+        let (files, _embeds) = crate::test_parse_files(ident, input);
+        let mut codegen = super::Codegen { files, ..Default::default() };
 
         codegen.generate();
 
diff --git a/lang/tests/codegen_tests_directives.txt b/lang/tests/codegen_tests_directives.txt
index 9eba6834..bc3f0470 100644
--- a/lang/tests/codegen_tests_directives.txt
+++ b/lang/tests/codegen_tests_directives.txt
@@ -1,6 +1,6 @@
 main:
-    ADDI64 r254, r254, -88d
-    ST r31, r254, 16a, 72h
+    ADDI64 r254, r254, -96d
+    ST r31, r254, 16a, 80h
     LI64 r32, 10d
     LI64 r33, 30d
     LI64 r34, 40d
@@ -18,11 +18,13 @@ main:
     LI64 r6, 6d
     ECA 
     CP r39, r1
+    LRA r40, r0, :arbitrary text
+
     LI64 r1, 0d
-    LD r31, r254, 16a, 72h
-    ADDI64 r254, r254, 88d
+    LD r31, r254, 16a, 80h
+    ADDI64 r254, r254, 96d
     JALA r0, r31, 0a
 ev: Ecall
-code size: 233
+code size: 255
 ret: 0
 status: Ok(())
diff --git a/lang/tests/codegen_tests_pointers.txt b/lang/tests/codegen_tests_pointers.txt
index d573cefa..6ffbf5bf 100644
--- a/lang/tests/codegen_tests_pointers.txt
+++ b/lang/tests/codegen_tests_pointers.txt
@@ -6,20 +6,31 @@ drop:
     ADDI64 r254, r254, 16d
     JALA r0, r31, 0a
 main:
-    ADDI64 r254, r254, -40d
-    ST r31, r254, 8a, 32h
+    ADDI64 r254, r254, -48d
+    ST r31, r254, 8a, 40h
     LI64 r32, 1d
     ST r32, r254, 0a, 8h
     ADDI64 r32, r254, 0d
+    LI64 r33, 1000d
+    CP r34, r32
+    CP r35, r33
+    MULI64 r35, r35, 8d
+    ADD64 r34, r34, r35
+    ADDI64 r32, r34, -16d
+    CP r34, r33
+    ADDI64 r34, r34, -2d
+    CP r35, r34
+    MULI64 r35, r35, 8d
+    SUB64 r32, r32, r35
     CP r2, r32
     JAL r31, r0, :modify
     LD r2, r254, 0a, 8h
     JAL r31, r0, :drop
-    CP r33, r32
-    LD r34, r33, 0a, 8h
-    ADDI64 r1, r34, -2d
-    LD r31, r254, 8a, 32h
-    ADDI64 r254, r254, 40d
+    CP r34, r32
+    LD r35, r34, 0a, 8h
+    ADDI64 r1, r35, -2d
+    LD r31, r254, 8a, 40h
+    ADDI64 r254, r254, 48d
     JALA r0, r31, 0a
 modify:
     ADDI64 r254, r254, -32d
@@ -31,6 +42,6 @@ modify:
     LD r31, r254, 0a, 32h
     ADDI64 r254, r254, 32d
     JALA r0, r31, 0a
-code size: 308
+code size: 382
 ret: 0
 status: Ok(())