Skip to content

Commit

Permalink
CURRENT TESTS PASSED
Browse files Browse the repository at this point in the history
'fixed' string ABI, hacky!
  • Loading branch information
pannous committed Dec 2, 2024
1 parent bc8cbf0 commit be7b83f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 30 deletions.
Binary file modified docs/assets/wasp-hosted.wasm
Binary file not shown.
3 changes: 2 additions & 1 deletion docs/examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ let exampleCode = {
// fibonacci_juliaesque: `fib 0 :=0; fib 1 := 1; fib n := fib(n - 1) + fib(n - 2)\n\nfib(10)`,
// fibonacci2: `fib n := n < 3 ? 1 : fib(n - 1) + fib(n - 2)\n\n`,
paint2d: `ctx.fillStyle = 'red'; ctx.fillRect(10, 10, 150, 100)`,
html: `html: h1: "Hello, World!"`,
html: `html{bold{"Hello"}}`,
// html: `html: h1: "Hello, World!"`,
// html: `html: <h1>Hello, World!</h1>`, // operator missing: <
alert: 'script: alert("Hello, World!")',
javascript: `html: div id="app"; app.innerHTML = "Hello, World!"`,
Expand Down
39 changes: 22 additions & 17 deletions docs/wasp.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function terminate() {
// if(sure)throw
}

function createHtml(parent, innerHtml) {
function createHtml(parent, innerHtml) { // via emitHtml
let element = document.createElement("div"); // todo tag
element.innerHTML = chars(innerHtml, app.memory);
if (!parent) parent = document.body;
Expand Down Expand Up @@ -157,8 +157,7 @@ function matrix_multiply(a, b, k = 1) {
}

function smartResult(object, mem = memory) { // returns BigInt smart pointer to object
// if(is_smart_pointer(object))
// return parseSmartResult(object)
// if(is_smart_pointer(object))return object
last_result = object
if (typeof object === "number")
return BigInt(object)
Expand Down Expand Up @@ -355,17 +354,18 @@ let imports = {
if (ref && typeof ref[prop] !== 'undefined') {
let val = ref[prop];
print("getExternRefPropertyValue OK ", ref, prop, val, typeof val)
// if (typeof val != "string") val = JSON.stringify(val) // todo, just
return smartResult(val, app.memory)
// if (typeof val != "string") val = JSON.stringify(val)
// return chars(val, app.memory)
// return string(val, app.memory)
} else if (ref && typeof ref.getAttribute === 'function') {
// check attribute
let attribute = ref.getAttribute(prop);
print("getExternRefPropertyValue OK! ", ref, prop, attribute)
// return String(attribute)
return chars(attribute, app.memory)
// return smartResult(attribute)
// if (typeof attribute != "string") val = JSON.stringify(attribute)
// return String(attribute, app.memory)
// return chars(attribute, app.memory)
return smartResult(attribute, app.memory)
} else {
throw new Error(`'${prop}' is not a property of the provided reference`);
}
Expand Down Expand Up @@ -453,25 +453,30 @@ function string(data, mem = memory) { // wasm<>js interop
switch (typeof data) {
case "string":
// todo use HEAP_END of APP, not of compiler! lol
while (HEAP_END % 8) HEAP_END++
while (HEAP_END % 8) HEAP_END++ // align to 8 bytes
let p = HEAP_END
new_int(HEAP_END + 12, mem) // pointer to chars = string_start +
new_int(HEAP_END + 12, mem) // pointer to chars = string_start + 20 TODO 12 vs 20 in c++/ABI
new_int(data.length, mem)
new_int(string_header_32, mem)
// new_long(0, mem) // 8 byte *codepoints 64 bit in c++
// new_int(0, mem) // 4 byte *codepoints 32 bit in WASM !!!
// new_int(-1, mem) // codepoint_count
// new_int(0, mem) // shared reference
chars(data, mem);
return p;
case "bigint":
case "number":
default:
let pointer = read_int32(data, mem);
let length = read_int32(data + 4, mem);
let kind = read_int32(data + 8, mem);
if (kind != string_header_32) {
console.log("missing string_header_32 kind", kind, pointer, length, data)
if (!pointer) return load_chars(data, length, mem);
}
// else console.log("found string_header_32", pointer, length, data)

let kind = read_int32(data + 8, mem); // todo not part of string ABI!
if (kind == length) ;//todo("string_header_32 kind==length HOW?");
else if (kind != string_header_32) {
// console.log("TODO missing string_header_32 kind", kind, pointer, length, data)
// todo mixing string_header_32 for strings and other chars BAD!!
if (!kind) return load_chars(pointer, length, mem);// todo messed up ABI!!
return load_chars(data, -1, mem);
} else console.log("found string_header_32", pointer, length, data)
if (!pointer) {
console.log("NO chars to read")
debugMemory(data - 10, 20, mem)
Expand Down Expand Up @@ -539,7 +544,7 @@ function new_int(val, mem = memory) {
function new_long(val) {
// memory.setUint32(addr + 0, val, true);
// memory.setUint32(addr + 4, Math.floor(val / 4294967296), true);
let buf = new Uint64Array(memory.buffer, HEAP_END / 8, mem.length); // todo: /8??
let buf = new Uint64Array(memory.buffer, HEAP_END, mem.length); // todo: /8??
buf[0] = val
HEAP_END += 8
}
Expand Down
2 changes: 1 addition & 1 deletion source/Angle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2215,7 +2215,7 @@ Node smartNode32(int smartPointer32) {
// check(arr.type=…
return arr;
}
if ((result & 0xF0000000) == string_header_32 /* and abi=wasp */ ) {
if ((result & 0xFF000000) == string_header_32 /* and abi=wasp */ ) {
// smart pointer for string
return Node(((char *) wasm_memory) + smart_pointer);
}
Expand Down
4 changes: 2 additions & 2 deletions source/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ static bool tracing = false; // todo
#if MY_WASM and DEBUG
static bool tracing = true;
#elif DEBUG
//static bool tracing = true;
static bool tracing = false;
static bool tracing = true;
//static bool tracing = false;
#else
//static bool tracing = true;
static bool tracing = false;
Expand Down
2 changes: 2 additions & 0 deletions source/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void testVectorShim() {

void testHtmlWasp() {
eval("html{bold{Hello}}"); // => <html><body><bold>Hello</bold></body></html> via appendChild bold to body
eval("html: h1: 'Hello, World!'"); // => <html><h1>Hello, World!</h1></html>
// eval("html{bold($myid style=red){Hello}}"); // => <bold id=myid style=red>Hello</bold>
}

Expand Down Expand Up @@ -3511,6 +3512,7 @@ void pleaseFix() {
// 2022-12-28 : 3 sec WITH runtime_emit, wasmedge on M1 WOW ALL TESTS PASSING
// ⚠️ CANNOT USE assert_emit in WASM! ONLY via void testRun();
void testCurrent() {
testHtmlWasp();
testFlags();
testTypes();
skip(
Expand Down
37 changes: 28 additions & 9 deletions source/wasm_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,11 +561,30 @@ Code emitPrimitiveArray(Node &node, Function &context) {
// extern "C" ExternRef createHtml(ExternRef parent /*0*/,chars innerHTML); // html{bold{Hello}} => appendChild bold to body
[[nodiscard]]
Code emitHtml(Node &node, Function &function, ExternRef parent = 0) {
static ExternRef previous = (void *) -1;
Code code;
if (parent)code.add(emitData(*new Node(parent), function));
if (node.name == "html") {
for (auto &child: node)
code.add(emitHtml(child, function, parent));// html is not parent
// printf("emitHtml node %s", node.serialize().data);
printf("emitHtml code %d", code.length);
return code;
}
if (parent == previous);// use previous return as parent (on stack)
else if (parent)code.add(emitData(*new Node(parent), function));
else code.add(emitCall(*new Node("getDocumentBody"), function));
code.add(emitString(node, function));
// else code.addConst32(0); // get document body in js
if (node.kind == strings)
code.add(emitString(node, function));
else
code.add(emitString(*new Node("<"s + node.name + ">"), function));
code.add(emitCall(*new Node("createHtml"), function));
trace(node.name);
for (auto &child: node) {
code.add(emitHtml(child, function, previous));// html is not parent
}
printf("emitHtml code %d", code.length);
// printf("emitHtml node %s", node.serialize().data);
return code;
}

Expand Down Expand Up @@ -1306,14 +1325,14 @@ Code emitString(Node &node, Function &context) {
} else if (as_c_io_vector) { // wasp abi:
emitIntData(data_index_end + 8, false);// char* for ciov, redundant but also acts as checksum
emitIntData(string.length, false);
} else { // wasp abi:

emitIntData(string_header_32, false);
emitIntData(data_index_end + 20, false);
} else { // ⚠️ WASP ABI is NOT the same as String, because pointer are 4/8 bit and we ignore other fields!!
// ⚠️ ANY CHANGE HERE NEEDS TO BE REFLECTED in wasp.js and smartNode (and getField??)
emitIntData(data_index_end + 20, false);// 32 bit 'pointer'
emitIntData(string.length, false);
emitIntData(1, false);// iovs len?
// emitIntData(string_header_32, false); WASP ABI is NOT the same as String ^^
emitIntData(1, false);// iovs len? // todo: know what you are doing!
// emitIntData(string.codepoint_count, false);// type + child_pointer in node
emitLongData(data_index_end + 8, false);// POINTER to char[] which just follows:
emitLongData(data_index_end + 8, false);// 64 bit POINTER to char[] AGAIN!? which just follows:
}
int chars_start = data_index_end;
// the actual string content:
Expand All @@ -1327,7 +1346,7 @@ Code emitString(Node &node, Function &context) {
last_type = stringp;
last_object_pointer = last_pointer;

if (use_wasm_strings) // via data instead of string_const
if (use_wasm_strings) // prepend length via data instead of string_const
return Code().addInt(string.length).addInt(chars_start).addOpcode(string_new_wtf8);

return Code().addConst32(chars_start);// direct data!
Expand Down

0 comments on commit be7b83f

Please sign in to comment.