From 52b46997bd9c05ab8377b87f4e7e7538a2518549 Mon Sep 17 00:00:00 2001 From: Ilia Lebedev Date: Thu, 12 Sep 2024 15:31:02 +0100 Subject: [PATCH 1/3] make it work on zig 0.13 --- .gitignore | 6 ++++ .prettierrc | 3 ++ build.zig | 29 ++++++++++++++++ index.html | 2 +- package.json | 15 ++++++++ pnpm-lock.yaml | 24 +++++++++++++ zigdom.zig => src/zigdom.zig | 9 ++--- zigdom.js | 64 +++++++++++++++++------------------ zigdom.wasm | Bin 2360 -> 0 bytes 9 files changed, 115 insertions(+), 37 deletions(-) create mode 100644 .prettierrc create mode 100644 build.zig create mode 100644 package.json create mode 100644 pnpm-lock.yaml rename zigdom.zig => src/zigdom.zig (95%) delete mode 100755 zigdom.wasm diff --git a/.gitignore b/.gitignore index 1153b96..58b4f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ +.idea/ +.zig-cache/ +zig-out/ + +node_modules/ + *.o zig-cache/zigdom.h zigdom.o diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..8db60ca --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..432002a --- /dev/null +++ b/build.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +const number_of_pages = 1; + +pub fn build(b: *std.Build) void { + const target = b.resolveTargetQuery(.{ + .cpu_arch = .wasm32, + .os_tag = .freestanding, + }); + + const exe = b.addExecutable(.{ + .name = "zigdom", + .root_source_file = b.path("src/zigdom.zig"), + .target = target, + .optimize = .ReleaseSmall, + }); + + // + exe.global_base = 0; + exe.entry = .disabled; + exe.rdynamic = true; + // exe.import_memory = true; + exe.stack_size = std.wasm.page_size / 2; + + exe.initial_memory = std.wasm.page_size * number_of_pages; + exe.max_memory = std.wasm.page_size * number_of_pages; + + b.installArtifact(exe); +} diff --git a/index.html b/index.html index c71d44c..73cae2d 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ - \ No newline at end of file diff --git a/src/zigdom.zig b/src/zigdom.zig index ec5fb89..2411082 100644 --- a/src/zigdom.zig +++ b/src/zigdom.zig @@ -1,11 +1,13 @@ // https://github.com/shritesh/zig-wasm-dom -extern "document" fn query_selector(selector_ptr: [*]const u8, selector_len: usize) usize; -extern "document" fn create_element(tag_name_ptr: [*]const u8, tag_name_len: usize) usize; -extern "document" fn create_text_node(data_ptr: [*]const u8, data_len: usize) usize; -extern "element" fn set_attribute(element_id: usize, name_ptr: [*]const u8, name_len: usize, value_ptr: [*]const u8, value_len: usize) void; -extern "element" fn get_attribute(element_id: usize, name_ptr: [*]const u8, name_len: usize, value_ptr: *[*]u8, value_len: *usize) bool; -extern "event_target" fn add_event_listener(event_target_id: usize, event_ptr: [*]const u8, event_len: usize, event_id: usize) void; -extern "window" fn alert(msg_ptr: [*]const u8, msg_len: usize) void; +const string = [*]const u8; + +extern "document" fn query_selector(selector_ptr: string, selector_len: usize) usize; +extern "document" fn create_element(tag_name_ptr: string, tag_name_len: usize) usize; +extern "document" fn create_text_node(data_ptr: string, data_len: usize) usize; +extern "element" fn set_attribute(element_id: usize, name_ptr: string, name_len: usize, value_ptr: string, value_len: usize) void; +extern "element" fn get_attribute(element_id: usize, name_ptr: string, name_len: usize, value_ptr: *[*]u8, value_len: *usize) bool; +extern "event_target" fn add_event_listener(event_target_id: usize, event_ptr: string, event_len: usize, event_id: usize) void; +extern "window" fn alert(msg_ptr: string, msg_len: usize) void; extern "node" fn append_child(node_id: usize, child_id: usize) usize; extern "zig" fn release_object(object_id: usize) void; @@ -115,7 +117,7 @@ fn attach_listener(node: usize, event_name: []const u8, event_id: eventId) void add_event_listener(node, event_name.ptr, event_name.len, @intFromEnum(event_id)); } -export fn dispatchEvent(id: u32) void { +export fn dispatch_event(id: u32) void { const e: eventId = @enumFromInt(id); switch (e) { eventId.Submit => on_submit_event(), diff --git a/zigdom.js b/zigdom.js index 6c6fa18..bd4c61a 100644 --- a/zigdom.js +++ b/zigdom.js @@ -1,24 +1,31 @@ -const getString = function (ptr, len) { +const zigdom = { + objects: [], + exports: undefined, +}; + +window.zigdom = zigdom; + +function getString(ptr, len) { const slice = zigdom.exports.memory.buffer.slice(ptr, ptr + len); const textDecoder = new TextDecoder(); return textDecoder.decode(slice); -}; +} -const pushObject = function (object) { +function pushObject(object) { return zigdom.objects.push(object); -}; +} -const getObject = function (objId) { +function getObject(objId) { return zigdom.objects[objId - 1]; -}; +} -const dispatch = function (eventId) { +function dispatch(eventId) { return function () { - zigdom.exports.dispatchEvent(eventId); + zigdom.exports.dispatch_event(eventId); }; -}; +} -const elementSetAttribute = function ( +function elementSetAttribute( node_id, name_ptr, name_len, @@ -29,9 +36,14 @@ const elementSetAttribute = function ( const attribute_name = getString(name_ptr, name_len); const value = getString(value_ptr, value_len); node[attribute_name] = value; -}; +} + +function writeU32ToMemory(memory, address, value) { + const mem_result_address = new DataView(memory.buffer, address, 4); + mem_result_address.setUint32(0, value, true); +} -const elementGetAttribute = function ( +function elementGetAttribute( node_id, name_ptr, name_len, @@ -44,7 +56,7 @@ const elementGetAttribute = function ( // convert result into Uint8Array const textEncoder = new TextEncoder(); const resultArray = textEncoder.encode(result); - var len = resultArray.length; + const len = resultArray.length; if (len === 0) { return false; @@ -56,58 +68,41 @@ const elementGetAttribute = function ( throw 'Cannot allocate memory'; } - // write the array to the memory - const mem_result = new DataView(zigdom.exports.memory.buffer, ptr, len); - for (let i = 0; i < len; ++i) { - mem_result.setUint8(i, resultArray[i], true); - } + const uint8array = new Uint8Array(zigdom.exports.memory.buffer); + uint8array.set(resultArray, ptr); // write the address of the result array to result_address_ptr - const mem_result_address = new DataView( - zigdom.exports.memory.buffer, - result_address_ptr, - 32 / 8, - ); - mem_result_address.setUint32(0, ptr, true); - - //write the size of the result array to result_address_ptr_len_ptr - const mem_result_address_len = new DataView( - zigdom.exports.memory.buffer, - result_address_len_ptr, - 32 / 8, - ); - mem_result_address_len.setUint32(0, len, true); + writeU32ToMemory(zigdom.exports.memory, result_address_ptr, ptr); + + // write the size of the result array to result_address_ptr_len_ptr + writeU32ToMemory(zigdom.exports.memory, result_address_len_ptr, len); // return if success? (optional) return true; -}; -const eventTargetAddEventListener = function ( - objId, - event_ptr, - event_len, - eventId, -) { +} + +function eventTargetAddEventListener(objId, event_ptr, event_len, eventId) { const node = getObject(objId); const ev = getString(event_ptr, event_len); node.addEventListener(ev, dispatch(eventId)); -}; +} -const documentQuerySelector = function (selector_ptr, selector_len) { +function documentQuerySelector(selector_ptr, selector_len) { const selector = getString(selector_ptr, selector_len); return pushObject(document.querySelector(selector)); -}; +} -const documentCreateElement = function (tag_name_ptr, tag_name_len) { +function documentCreateElement(tag_name_ptr, tag_name_len) { const tag_name = getString(tag_name_ptr, tag_name_len); return pushObject(document.createElement(tag_name)); -}; +} -const documentCreateTextNode = function (data_ptr, data_len) { - data = getString(data_ptr, data_len); +function documentCreateTextNode(data_ptr, data_len) { + const data = getString(data_ptr, data_len); return pushObject(document.createTextNode(data)); -}; +} -const nodeAppendChild = function (node_id, child_id) { +function nodeAppendChild(node_id, child_id) { const node = getObject(node_id); const child = getObject(child_id); @@ -116,49 +111,61 @@ const nodeAppendChild = function (node_id, child_id) { } return pushObject(node.appendChild(child)); -}; +} -const windowAlert = function (msg_ptr, msg_len) { +function windowAlert(msg_ptr, msg_len) { const msg = getString(msg_ptr, msg_len); + // console.log('>', msg); alert(msg); -}; +} -const zigReleaseObject = function (object_id) { +function zigReleaseObject(object_id) { zigdom.objects[object_id - 1] = undefined; -}; +} + +function launch(wasmInstance) { + zigdom.exports = wasmInstance.instance.exports; -const launch = function (result) { - zigdom.exports = result.instance.exports; if (!zigdom.exports.launch_export()) { throw 'Launch Error'; } -}; +} -const zigdom = { - objects: [], - imports: { - document: { - query_selector: documentQuerySelector, - create_element: documentCreateElement, - create_text_node: documentCreateTextNode, - }, - element: { - set_attribute: elementSetAttribute, - get_attribute: elementGetAttribute, - }, - event_target: { - add_event_listener: eventTargetAddEventListener, - }, - node: { - append_child: nodeAppendChild, - }, - window: { - alert: windowAlert, - }, - zig: { - release_object: zigReleaseObject, - }, +const wasmImports = { + document: { + query_selector: documentQuerySelector, + create_element: documentCreateElement, + create_text_node: documentCreateTextNode, + }, + element: { + set_attribute: elementSetAttribute, + get_attribute: elementGetAttribute, + }, + event_target: { + add_event_listener: eventTargetAddEventListener, + }, + node: { + append_child: nodeAppendChild, + }, + window: { + alert: windowAlert, + }, + zig: { + release_object: zigReleaseObject, }, - launch, - exports: undefined, }; + +async function run() { + const response = await fetch('zig-out/bin/zigdom.wasm'); + + if (!response.ok) { + throw new Error("wasm file can't be loaded"); + } + + const buffer = await response.arrayBuffer(); + const instance = await WebAssembly.instantiate(buffer, wasmImports); + + launch(instance); +} + +run(); From 27e864ad28b32fd390650fb18d1350fc90533269 Mon Sep 17 00:00:00 2001 From: Ilia Lebedev Date: Thu, 12 Sep 2024 16:46:33 +0100 Subject: [PATCH 3/3] updates --- README.md | 4 +++- zig-out/bin/zigdom.wasm | Bin 0 -> 2289 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100755 zig-out/bin/zigdom.wasm diff --git a/README.md b/README.md index a2663fa..cf0ff3d 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,6 @@ An example demonstrating Zig interacting with the DOM via JS. -Compile with `zig build-lib zigdom.zig -target wasm32-freestanding -dynamic -OReleaseSmall` +Forked from https://github.com/shritesh/zig-wasm-dom + +Compile with `zig build` diff --git a/zig-out/bin/zigdom.wasm b/zig-out/bin/zigdom.wasm new file mode 100755 index 0000000000000000000000000000000000000000..7b3a17e20f5f1805936e40f1764f6f8fd73f9a8a GIT binary patch literal 2289 zcmZuzJC7Sx6h8Mc5AWE!lXS4noq-~epbg?7u{TmkB7_!+CZh3r?IG(~zdhc~OR)n4 zBAya7bW~`iP|(vs1szSKNKo(-_y^%TcRZ6s$w)KzanAY9cOLiJ)R_+j5sCMkd)|^C z+S5FU<$8^YWz=R&LEo=q-wSKQ)(3U#@z+mZ%!B4?0S0+xNb3?k$x=c&azICwbzbFH?t!c zw2RIRK2LXgy>_`V=+BF6l+DPiZR53VkzFg=qj4`It$Ap6CX;N`Yj+R&gC1#hqknaC z1_zya)*kQYpg_KAMt%@BJhdSrYG_YPgw~!GLP$SER_uRY$S8PS`@?KFo?Vx;+3U|I zouYeC@}Wj+&{>Rld2KRA5;mgtF>2B73ltCg9G_+$mo{R0p(TtsBg0hk&`c@5!)OM^hPG1$ zxuvt}4+co}iIMjHgZmF|KxUL>C4Ju9I|0Bche%BkJ>%B?>fBTOF+)cn5a%V+=yxSH zmdw|#oQ{q^VV%^mPlQ8Dz`))uBZxnBVtK9%%*YEZ0;hF+_GhQHRXTF8Ke!#gvg4%G zurU0wgtZjkWnl35a&7RLbAx=EdIRA?bpwh*0itp~FwTg1rdPpN!( z2$qjKU6uV~(BV4KJW%4nqmPO`+$g$N$o=O~rvx?HjdHR5R z2=kk!ar4%R5tmzF;M<@`L%R}rvY~cNXf}3R5(Ax;Z1lpt6T4bYacn{(-`!4;&%>l? z8YfAM12>_Kivtr}PB!I^;s$CO2_7a&wwf{mN4Cq;EgMYJ*aq_>D@OgB)^EVhE0l~Ri7{uZgDJ-_$;|1#1c|u zNHZ@!Kf-0NI@ZYNHef*^RYrk^y^SSEs^h8AMisL+h?@z30=Zu1C@OGq7YX@9ePmf5 z#7%Y;@1g*IapM~{UB&KmdE3xo{4KNRy72yc+$-GZ|FAN5vt5~UBc7RG5$5VoLP;8BKsWi&mEmg%c2e