Skip to content

Commit

Permalink
smartResult … WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
pannous committed Dec 28, 2023
1 parent ec02feb commit 1dcd998
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 49 deletions.
2 changes: 2 additions & 0 deletions source/Code.h
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,8 @@ enum string_ops { // on Valtype stringref = 0x64
string_new_wtf8_array = 0xfbb5, // [gc]
string_encode_lossy_utf8_array = 0xfbb6, // [gc]
string_encode_wtf8_array = 0xfbb7, // [gc]

// stringrefs ::= section_14(0x00 vec(vec(u8)))
};


Expand Down
5 changes: 3 additions & 2 deletions source/Wasp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ int SERVER_PORT = 1234;
//bool eval_via_emit = false;// not all tests yet
bool eval_via_emit = true;// << todo! assert_is(…)

// WE DON'T NEED THIS, we can just use CANONICAL ABI lowering, e.g. for strings: [i32, i32]
bool use_wasm_structs = false;// struct in wat
// WE DON'T NEED THIS in main, we can just use CANONICAL ABI lowering, e.g. for strings: [i32, i32]
// WE DO NEED THIS for easier WASM to js calls, avoiding new_string
bool use_wasm_strings = false;// stringref in wat
bool use_wasm_structs = false;// struct in wat
bool use_wasm_arrays = false; // array in wat


Expand Down
13 changes: 7 additions & 6 deletions source/WebApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,13 @@ int64 open_webview(String url = "") {
view.terminate();
return s;
});
view.bind("new_string", [](std::string s) -> std::string {
const std::string &string = webview::json_parse(s, "", 0);
String data = String(string.data());
Node &node = *new Node(data, strings);// todo?
return to_string(node.toSmartPointer());// parsed as BigInt later
});
// doesn't work because it returns async Promise, which can't be used in wasm
// view.bind("new_string", [](std::string s) -> std::string {
// const std::string &string = webview::json_parse(s, "", 0);
// String data = String(string.data());
// Node &node = *new Node(data, strings);// todo?
// return to_string(node.toSmartPointer());// parsed as BigInt later
// });
view.bind("wasm_done", [](std::string s) -> std::string {
printf("wasm_done result json = %s ", s.c_str());
const std::string &string = webview::json_parse(s, "", 0);
Expand Down
54 changes: 33 additions & 21 deletions source/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,40 +110,43 @@
function is_smart_pointer(result) {
let got_smart_pointer = Number.isInteger(result) && (result >= 0x10000000 || result <= -0x10000000);
if (typeof result === "bigint") got_smart_pointer = result >= BigInt(0x4000000000000000)
if (typeof result === "bigint") got_smart_pointer ||= (result & string_header_64)
if (typeof result === "bigint" || got_smart_pointer)
console.log(">>> 0x", hex(result), got_smart_pointer ? " SMART " : "");
if (Array.isArray(result)) got_smart_pointer = true;// multivalue of length 2 always assumed smart pair
return got_smart_pointer;
}

// to it wasp side in WebApp.cpp !
// function new_string(str) {
// let len = str.length;
// let ptr = memory.buffer.byteLength - str.length - 1;
// for (let i = 0; i < len; i++) {
// memory[ptr + i] = str.charCodeAt(i);
// }
// memory[ptr + len] = 0;
// return BigInt(ptr) | string_header_64;
// }
// this is wasm side, can't do it wasp side in WebApp.cpp because of async bind!
function new_string(str) {
let len = str.length;
let ptr = memory.buffer.byteLength - str.length - 1;
for (let i = 0; i < len; i++) {
memory[ptr + i] = str.charCodeAt(i);
}
memory[ptr + len] = 0;
return BigInt(ptr) | string_header_64;
}

// async NOT WORKING in wasm: Failed to parse String to BigInt
function smartResult(object) {
function smartResult(object) { // returns BigInt smart pointer to object
// if(is_smart_pointer(object))
// return parseSmartResult(object)
if (typeof object === "number")
return BigInt(object)
if (typeof object === "string" && !isNaN(object))
return BigInt(object)
// if (typeof object === "object")
// return -123;// String(object) JSON.stringify(
// return -123;//
try {
print("smartResult: ", object, "trying to parse to BigInt")
print("typeof object", typeof object)
print("object", object)
print(" !isNaN(object)", !isNaN(object))
// // let wrapped= await new_string(serialized) //
return BigInt(object)
let serialized = String(object);
// if() serialized=JSON.stringify(object)
let wrapped = new_string(serialized) | string_header_64;
return BigInt(wrapped) // to be consumed by wasm, potentially returned to wasp via main and wasm_done
} catch (ex) {
// todo error handling via print!
console.error("smartResult: ", object, "failed to parse to BigInt", ex)
Expand All @@ -154,6 +157,7 @@
function parseSmartResult(data = 0) {
var type = -1
var address = data;
print("smartResult: ", hex(data))
if (!is_smart_pointer(data)) return data;
if (Array.isArray(data)) { // multivalue return always 'smarty
let _a = data
Expand All @@ -166,13 +170,20 @@
} else { // smartpointer32
type = data & 0xF0000000;
address = data & 0x0FFFFFFF;
print("smartResult 32 ", hex(data), hex(type), hex(address))
return string(address);
}
print("smartResult: ", hex(type), hex(data), hex(address))

if (type === 0xC0 || type === 0x10000000 || type === string_header_64 || type === string_header_64 / 0x100000000n)
return string(address); // chars
if (type === 0xC0 || type === 0x10000000 || type === 0x100000 || type === string_header_64 || type === string_header_64 / 0x100000000n) {
print("smartResult: string", hex(data))
let str = string(Number(data), 10);
print("smartResult: string", hex(data), str)
return str; // chars
}
if (type === 0x7E) // float64
return rei
return reinterpretInt64AsFloat64(data) // wasp.js
// return reinterpret_f64(data);
if (!Number.isInteger(type))
console.error("smart type should be an integer: ", type, "of", data);
if (BigInt(type) & BigInt(0x40000000)) {// array
Expand Down Expand Up @@ -274,14 +285,14 @@
print("CALLING getExternRefProperty", ref, prop)
if (ref && typeof ref[prop] !== 'undefined') {
print("getExternRefProperty OK ", ref, prop, ref[prop])
// return smartResult(ref[prop])
return String(ref[prop])

return smartResult(ref[prop])
// return String(ref[prop])
} else if (ref && typeof ref.getAttribute === 'function') {
// check attribute
let attribute = ref.getAttribute(prop);
print("getExternRefProperty OK ", ref, prop, attribute)
return String(attribute)
// return String(attribute)
return smartResult(attribute)
} else {
throw new Error(`'${prop}' is not a property of the provided reference`);
}
Expand Down Expand Up @@ -367,6 +378,7 @@
let result = main()
print("result")
print(result)
print(hex(result))
let smart_result = parseSmartResult(result); // unwrap
print("smart_result", smart_result)
wasm_done(String(smart_result)); // wrap!
Expand Down
6 changes: 3 additions & 3 deletions source/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void testDomProperty() {
#endif

result = eval("getExternRefProperty($canvas,'width')"); // ok!!
check_eq(result.value.longy, 300);
check_eq(result.value.longy, 300); // only works because String "300" gets converted to BigInt 300
// result = eval("width='width';$canvas.width");
result = eval("$canvas.width");
check_eq(result.value.longy, 300);
Expand Down Expand Up @@ -3383,8 +3383,8 @@ void testCurrent() {
// assert_emit("puts('hi')", 8)
// testReplaceAll();
// testFetch();
// testDomProperty();
testInnerHtml();
testDomProperty();
// testInnerHtml();
return;
#if WEBAPP
#endif
Expand Down
35 changes: 18 additions & 17 deletions source/wasm_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2051,23 +2051,24 @@ Code emitExpression(Node &node, Function &context/*="wasp_main"*/) { // expressi

//extern "C" ExternRef createElement(ExternRef parent /*0*/, chars tag);
//extern "C" ExternRef createElement2(ExternRef parent /*0*/,chars tag,chars id,chars className,chars innerHTML);
//[[nodiscard]]
//Code emitHtmlWasp(Node &node, Function &function, ExternRef parent = 0) {
// Code code;
// code.add(emitData(*new Node(parent), function));
// if (node.name == "html") {}
// else {
//// if(parent)code.add(emitData(*new Node(parent), function));
// code.add(emitString(node, function));
// code.add(emitCall(*new Node("createElement"), function));
//// addVariable(node.name, parent); // can't, must be in analyze!
// }
// for (Node &child: node) {
//// getVariable( parent);
// code.add(emitHtml(child, function, 0));
// }
// return code;
//}
[[nodiscard]]
Code emitHtmlWasp(Node &node, Function &function, ExternRef parent = 0) {
Code code;
if (node.name == "html") {
code.add(emitCall(*new Node("getDocumentBody"), function)); // document.body as parent
} else {
// if(parent)code.add(emitData(*new Node(parent), function)); todo ?
code.add(emitString(node, function));
code.add(emitCall(*new Node("createElement"), function));
// addVariable(node.name, parent); // can't, must be in analyze!
}
for (Node &child: node) {
// getVariable( parent); // can't, must be in analyze or on top of stack!
code.add(emitHtml(child, function, 0));
code.add(drop);// we don't need this as parent, revert to original parent
}
return code;
}

Primitive elementType(Type type32) {
if (type32 == stringp)return byte_char;
Expand Down

0 comments on commit 1dcd998

Please sign in to comment.