Skip to content

Commit

Permalink
CURRENT TESTS PASSED
Browse files Browse the repository at this point in the history
assert_emit("√3^2", 3);

in browser via import, no funclet
  • Loading branch information
pannous committed Nov 22, 2024
1 parent a628b68 commit 260d416
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 61 deletions.
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ if (NOT WASM)
# TO EXECUTE wasm provide _run_wasm :
# https://github.com/WebAssembly/wasm-c-api implemented by V8 Wabt Wasmtime Wasmer
# as of 2022-10 wasm-c-api encompasses multiple return values and reference types, but not yet threads.
# NO engine has (c-api) support for wit / component model as of 2024-12
# SET(WASMEDGE 1) # fastest, easiest, bestest. todo smart multi-value returns
SET(WASMEDGE 0) # no wit / component model as of 2024-10
SET(WASMEDGE 0)
SET(WASMTIME 1) # FASTEST but unstable / elusive bugs "object used with the wrong store" etc
# set(WEBAPP 1) # FAST!! WebView for electron like standalone apps and testing of browser features
# set(WEBAPP 1) # FAST!! WebView for electron like standalone apps and testing of browser features
# set(WASM3 1) # GOOD (backtrace…) wasm_runner_wasm3.cpp BEST API but dying to Russia :( 2022-12: last release on Jun 2, 2021
# set(MICRO 1) # WAMR 2023-02 still NOT M1 READY! wasm-micro-runtime => wasm_runner_micro.cpp TODO: use AOT/JIT mode!?
# SET(V8 1) # 2024-04 Exception: EXC_BAD_ACCESS (code=1, address=0x0) :( and VERY SLOW !?
# set(WABT 1) # 2022-12 broken! EXTREMELY SLOW on Mac M1! wasm_runner_wabt.cpp
# set(WASMX 1) # doesn't work: cannot insert imports or function types!
# set(WASMER 1) # only good for calling tested code, otherwise it gives ZERO info on what went wrong!
# set(WASMER 1) # only good for calling tested code, otherwise it gives ZERO info on what went wrong! Hates GC…
# others: WAVM WAMR
if (WEBAPP)
set(INCLUDE_MERGER 1) # should work !?
Expand Down
2 changes: 1 addition & 1 deletion docs/examples.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let exampleCode = {
hello: `"Hello, World!" // last item in root block is its return value, which is printed"`,
math: `√π^2`,
math2: `√π²`,
function: `square := it*it; square 3`,
lists: `a = [1, 2, 3]; a[1] == a#2`,
lists2: `a = [1, 2] + [3, 4]; a[2] == a#3 == 3`,
Expand Down
31 changes: 6 additions & 25 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html xmlns:https="http://www.w3.org/1999/xhtml">
<html>
<head>
<!-- ⚠️⚠️⚠️ https://wasp.pannous.com/ points to GITHUB page!! ⚠️⚠️⚠️ -->
<META CONTENT="text/html; charset=UTF-8" HTTP-EQUIV="CONTENT-TYPE"/>
Expand Down Expand Up @@ -42,26 +42,8 @@
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/show-hint.min.js"></script>-->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/javascript-hint.min.js"></script>-->

<script src="https://webassembly.github.io/wabt/demo/libwabt.js"></script>
<script>
WabtModule().then(function (wabt) {
window.wabt = wabt;
console.log('Wabt loaded');
// _wabt_write_text_module = wabt.writeTextModule;
// _wabt_read_binary = wabt.readBinary;
// _wabt_read_binary_module = wabt.readBinaryModule;
// _wabt_write_binary_spec_script = wabt.writeBinarySpecScript;
});

// for (var i = 0; i < examples.length; ++i) {
// var example = examples[i];
// var option = document.createElement('option');
// option.textContent = example.name;
// selectEl.appendChild(option);
// }
// selectEl.selectedIndex = 1;
// setExample(selectEl.selectedIndex);
</script>
<!-- <script src="https://webassembly.github.io/wabt/demo/libwabt.js"></script>-->
<!-- <script> WabtModule().then(function (wabt) {-->

</head>
<body style="background: floralwhite">
Expand All @@ -87,19 +69,18 @@ <h2>A new programming language for Wasm</h2>
</select>

<br/>
<textarea id="code" onkeyup="compile_and_run(editor.getValue())">√3^2</textarea>
<textarea id="code" onkeyup="compile_and_run(editor.getValue())" placeholder="wasp code">√3^2</textarea>
<br/>
<!-- <input id="input_file" onchange="readFile()" type="file"/>-->
<input checked id="check" type="checkbox"/> auto
<label for="check">auto</label><input checked id="check" type="checkbox"/>
<button onclick="compile_and_run(editor.getValue())">RUN!</button>
<button onclick="results.value=''">CLEAR</button>
<!-- spacer -->
<div style="width: 250px;display: inline-block; "></div>
<button onclick="download_file(editor.getValue(), 'source.wasp', 'wasp')" title="download wasp">💾 source.wasp</button>
<button onclick="download_file(wasm_buffer, 'compiled.wasm', 'wasm')" title="download wasm">💾 compiled.wasm</button>
<br/>
<textarea cols="80" id="results" placeholder="RESULT… press run to compile" rows="8">
</textarea>
<textarea cols="80" id="results" placeholder="RESULT… press run to compile" rows="8"></textarea>


<script>
Expand Down
13 changes: 9 additions & 4 deletions docs/wasp.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* Converts wasm types to/from JS objects via node() and string() as a shim for wasm GC types
* */
let Wasp = {}
let WASP_COMPILER = 'wasp.wasm' // without tests
// let WASP_COMPILER = 'wasp-hosted.wasm' // with tests and shortcuts
// let WASP_COMPILER = 'wasp.wasm' // without tests
let WASP_COMPILER = 'wasp-hosted.wasm' // with tests and shortcuts
// let WASP_RUNTIME = 'wasp-runtime.wasm'
let lib_folder_url = "https://pannous.github.io/wasp/lib/"

Expand Down Expand Up @@ -237,7 +237,12 @@ let imports = {
},

exit: terminate, // should be wasi.proc_exit!
// pow: Math.pow,
pow: (x, y) => x ** y,
pow: (x, y) => {
console.log("POW", x, y);
return x ** y
},
print: x => console.log(string(x)),
puti: x => console.log(x), // allows debugging of ints without format String allocation!
js_demangle: x => x,
Expand Down Expand Up @@ -550,7 +555,7 @@ class node {
serialize() {
if (!this.pointer) todo("only wasp nodes can be serialized");
if (!this.memory == memory)
todo("needs to serialize inside the correct memory!") // funclet.serialize()
todo("needs to serialize inside the correct memory!") // app.serialize()
return chars(runtime_exports.serialize(this.pointer));
}

Expand Down Expand Up @@ -939,7 +944,7 @@ async function run_wasm(buf_pointer, buf_size) {
// console.log("GOT raw ", result)
if (result < -0x100000000 || result > 0x100000000) {
if (!app.memory)
error("NO funclet.memory")
error("NO app.memory")
result = smartNode(result, 0, app.memory)
// result lives in emit.wasm!
// console.log("GOT nod ", nod)
Expand Down
24 changes: 15 additions & 9 deletions source/Angle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,11 +1692,12 @@ void addLibraryFunctionAsImport(Function &func) {
// auto function_known = functions.has(func.name);

// ⚠️ this function now lives inside Module AND as import inside "wasp_main" functions list, with different wasm_index!
#if WASM
Function& import=*new Function;
#else
bool function_known = functions.has(func.name);
//#if WASM
// Function& import=*new Function;
//#else
Function & import=functions[func.name];// copy function info from library/runtime to main module
#endif
//#endif
// if(function_known)
// import = functions[func.name];
if (import.is_declared)return;
Expand All @@ -1707,11 +1708,10 @@ void addLibraryFunctionAsImport(Function &func) {
import.is_import = true;
import.is_used = true;

#if WASM
bool function_known = functions.has(func.name);
if(not !function_known)
functions.add(func.name, import);
#endif
//#if WASM
// if(not function_known)
// functions.add(func.name, import);
//#endif
}

Function getWaspFunction(String name);
Expand Down Expand Up @@ -1750,6 +1750,7 @@ Function *findLibraryFunction(String name, bool searchAliases) {
libraries.add(&loadModule("wasp-runtime.wasm"));// on demand

// if(functions.has(name))return &functions[name]; // ⚠️ returning import with different wasm_index than in Module!
// todo in WASM
for (Module *library: libraries) {//} module_cache.valueList()) {
// todo : multiple signatures! concat(bytes, chars, …) eq(…)
int position = library->functions.position(name);
Expand Down Expand Up @@ -2085,6 +2086,11 @@ void preRegisterFunctions() {
functions["createHtml"].signature.add(externref, "parent").add(charp, "innerHtml").returns(externref);
functions["addScript"].import().signature.add(charp, "js");

//#if WASM // no funclets in browser (yet?)
functions["pow"].import();//.builtin();
functions["pow"].signature.add(float64).add(float64).returns(float64);


functions["getElementById"].import();//.builtin();
functions["getElementById"].signature.add(charp).returns(externref /*!!*/);
functions["getExternRefPropertyValue"].import();//.builtin();
Expand Down
6 changes: 5 additions & 1 deletion source/Angle.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ static chars function_list[] = {/*"abs" f64.abs operator! ,*/ "norm", "square",
"putx", "putc", "get", "set", "peek", "poke", "read",
"write",
"$" /* getElementById */,
// FUNCLETS via runtime for now:
"pow", "powi", "pow_long", "log", "log10", "log2",
"lowerCaseUTF",
0, 0, 0};// MUST END WITH 0, else BUG

//chars runtime_function_list[]={};
Expand All @@ -29,7 +32,8 @@ static chars wasi_function_list[] = {"proc_exit", "fd_write", "args_sizes_get",
// they get automatically linked when used without requiring the wasp runtime
// see aliases for discoverability
// todo: pre-fill list from current directory(s) / funclet registry / wapm
static chars funclet_list[] = {"pow", "powi", "pow_long", "log", "log10", "log2", "lowerCaseUTF", 0};
//static chars funclet_list[] = {"pow", "powi", "pow_long", "log", "log10", "log2", "lowerCaseUTF", 0};
static chars funclet_list[] = {};// LINK WITH RUNTIME!

static chars functor_list[] = {"if", "while", "go", "do", "until", 0};// MUST END WITH 0, else BUG

Expand Down
4 changes: 3 additions & 1 deletion source/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3212,7 +3212,9 @@ void assurances() {
// todo: merge with testAllWasm, move these to test_wasm.cpp
void testAllEmit() {
// WASM emit tests under the hood:
assert_emit("42", 42);// basics
assert_emit("√3^2", 3);// basics
// assert_emit("42", 42);// basics
// exit(42);
// assert_emit("√ π ²", pi);
// assert_emit("√π²", pi);

Expand Down
15 changes: 9 additions & 6 deletions source/wasm_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1751,16 +1751,16 @@ Code emitOperator(Node &node, Function &context) {
// code.add(emitCall(*new Node("pow"), context));
// if(last_value==0)code.addConst(1);
// if(last_value==1)return code;
#if MY_WASM
getWaspFunction("pow");
code.add(emitCall(*new Node("pow"), context));
#else
//#if MY_WASM
// getWaspFunction("pow");
// code.add(emitCall(*new Node("pow"), context));
//#else
if (last_type == int32) code.add(emitCall(*new Node("powi"), context));
else if (last_type == float32) code.add(emitCall(*new Node("powf"), context));
else if (last_type == float64) code.add(emitCall(*new Node("pow"), context));
else if (last_type == int64s) code.add(emitCall(*new Node("pow_long"), context));
else code.add(emitCall(*new Node("powi"), context));
#endif
//#endif
// else todo("^ power with type "s + typeName(last_type));
// 'powi' is a builtin with type 'long double (long double, long double)'
} else if (name.startsWith("-")) {
Expand Down Expand Up @@ -2723,7 +2723,10 @@ Code emitBlock(Node &node, Function &context) {
todo("last_type ref");
} else if (last_type == float64 and context.name == start) {
// hack smart pointers as main return: f64 has range which is never hit by int
block.addByte(i64_reinterpret_f64);
block.addByte(
i64_reinterpret_f64); // todo: not for _start in wasmtime... or 'unwrap' / print smart pointers via builtin
// block.add(emitCall(*new Node("print_smarty"), context)); // _Z5printd putf putd
// block.add(emitCall(*new Node("_Z5printd"), context));
last_type = i64;
} else if (last_type == byte_char or last_type == codepoint1) {
block.addByte(i64_extend_i32_u);
Expand Down
2 changes: 1 addition & 1 deletion source/wasm_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ void print(int l);
void print(int64 l);
//void print(Primitive l);

void print(double l);
void print(double l); // _Z5printd

void print(size_t l);

Expand Down
22 changes: 12 additions & 10 deletions source/wasmtime_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <wasm.h>
//#include <wasmtime.h>
#include "Util.h"
#include <math.h>

//#undef assert // assert.h:92 not as good!
//#define assert(condition) try{\
//if((condition)==0){printf("\n%s\n",#condition);error("assert FAILED");}else printf("\nassert OK: %s\n",#condition);\
//}catch(chars m){printf("\n%s\n%s\n%s:%d\n",m,#condition,__FILE__,__LINE__);exit(1);}


//#include <wasmtime.h>
#include "wasmtime.h"
#include "wasm_reader.h"
#include <assert.h>
Expand All @@ -24,6 +18,12 @@
#include "Util.h"
#include <math.h>

//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wvla-cxx-extension"

// wasm-c-api/src/wasm-v8.cc: extern bool FLAG_expose_gc;
// include/wasmtime/conf.h:#define WASMTIME_FEATURE_GC

static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap);

static wasm_engine_t *engine = NULL;
Expand Down Expand Up @@ -90,15 +90,15 @@ extern "C" int64_t run_wasm(unsigned char *data, int size) {
Module &meta = read_wasm(data, size);
int import_count = meta.import_count;
wasmtime_extern_t imports[import_count];
int i = 0;

int import_nr = 0;
for (const String &import_name: meta.import_names) {
if (import_name.empty()) break;
wasmtime_func_t func;
const wasm_functype_t *type0 = funcType(meta.functions[import_name].signature);
wasmtime_func_new(context, type0, link_import(import_name), NULL, NULL, &func);
wasmtime_extern_t import = { .kind = WASMTIME_EXTERN_FUNC, .of.func = func };
imports[i++] = import;
imports[import_nr++] = import;
// wasm_functype_delete(type0);
}

Expand Down Expand Up @@ -344,7 +344,7 @@ void test_lambda() {
#define wrap_fun(fun) [](void *, wasmtime_caller_t *, const wasmtime_val_t *, size_t, wasmtime_val_t *, size_t)->wasm_trap_t*{fun();return NULL;};

wasm_wrap *link_import(String name) {
// own WASI mock
// own WASI mock instead of https://docs.wasmtime.dev/c-api/wasi_8h.html
if (name == "fd_write") return &wrap_fd_write;
if (name == "args_get")return &wrap_args_get;
if (name == "args_sizes_get")return &wrap_args_sizes_get;
Expand Down Expand Up @@ -546,3 +546,5 @@ const wasm_functype_t *funcType(Signature &signature) {
error("missing signature mapping"s + signature.format());
return 0;
}

//#pragma clang diagnostic pop

0 comments on commit 260d416

Please sign in to comment.