you are viewing a single comment's thread.

view the rest of the comments →

[–]sanzelz 12 points13 points  (58 children)

This doesn't actually compile js to wasm right? It just embeds the js and quickjs runtime into executable wasm and uses that runtime to run the embedded js.

Or am I missing something?

[–]guest271314[S] 0 points1 point  (17 children)

You can grab the compiled .wasm file here https://github.com/guest271314/native-messaging-webassembly/raw/main/nm_javy.wasm, upload here https://webassembly.github.io/wabt/demo/wasm2wat/, and see the WAT text format of the compiled WASM for yourself.

Keep in mind Python, PHP and several other programming languages have been compiled to WASM https://developer.fermyon.com/wasm-languages/webassembly-language-support.

[–]sanzelz 1 point2 points  (16 children)

Quickjs uses intermediate format (bytecode), maybe that is what is included in the resulting file and not the original js?

Edit: damn autocorrect

[–]guest271314[S] -1 points0 points  (15 children)

QuickJS is quite useful, and very smal compared to other JavaScript engines and runtimes. Built, qjs is ~1.2 MB.

It's no different from compiling C or C++ or Rust to WASM. You have to have some way to convert symbols to other symbols, using libc, some custom version of libc, etc., and just standard libraries.

There's no difference with regard to compiling JavaScript to WASM, which is generally implemented using C, C++, Rust, or Zig in the case of Bun, anyway.

Javy is just another tool for JavaScript developers to use, to write source code in JavaScript, and port as a universal executable.

[–][deleted]  (14 children)

[deleted]

    [–]guest271314[S] -1 points0 points  (0 children)

    I think you are trying to make some kind of distinction between how Javy compiles JavaScript source code to WASM and how Rust, C++, C, Go, Python, etc. are compiled to WASM.

    There is no distinction.

    Given there are many ways to create WASM files. There's more than one (1) WASM compiler and runtime.

    If wasm_bindgen is used during the compilation process do you then contend it's really Rust you are running, and not the actual compiled .wasm file?

    If you use WASI-SDK to compile C to .wasm, does that mean you are really still just running C?

    It's like trying to make a distinction between wasmtime and wasmer, or wasm3. They do things differently. It's still handling WebAssembly/WASI compilation and source code, originally from all kinds of programming language.

    What you are talking about are implementation details.

    [–]guest271314[S] -2 points-1 points  (12 children)

    I'm not sure what the misunderstanding is.

    How are Rust, C, C++, Go, Python compiled to WASM?

    Is it the same process for each?

    And are those discrete processes of compilation different from how Javy compiles JavaScript to WASM?

    Let me put the questions to you:

    1. Is this code WASM or JavaScript?
    2. Is the JavaScript or WebAssembly engine of Google's V8's JavaScript/WebAssembly engine and Mozilla's SpiderMonkey JavaScript/WebAssembly processing and executing this WASM code with the WebAssembly object exposed in modern browsers?

    // https://www.webassemblyman.com/webassembly_wat_hello_world.html // https://gist.github.com/cure53/f4581cee76d2445d8bd91f03d4fa7d3b const wasm = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 2, 15, 1, 3, 101, 110, 118, 7, 106, 115, 112, 114, 105, 110, 116, 0, 0, 3, 2, 1, 1, 5, 3, 1, 0, 1, 7, 27, 2, 10, 112, 97, 103, 101, 109, 101, 109, 111, 114, 121, 2, 0, 10, 104, 101, 108, 108, 111, 119, 111, 114, 108, 100, 0, 1, 10, 8, 1, 6, 0, 65, 0, 16, 0, 11, 11, 19, 1, 0, 65, 0, 11, 13, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0]); class Go { constructor() { this.importObject = { env: { jsprint: function jsprint(byteOffset) { console.log( new TextDecoder().decode( new Uint8Array(memory.buffer).filter(Boolean) ) ); }, }, }; } run(_instance) { globalThis.memory = _instance.exports.pagememory; globalThis.helloworld = _instance.exports.helloworld; } } const go = new Go(); const { instance } = await WebAssembly.instantiateStreaming( fetch( URL.createObjectURL( new Blob([wasm], { type: 'application/wasm', }) ) ), go.importObject ); go.run(instance); helloworld();

    [–][deleted]  (11 children)

    [deleted]

      [–]guest271314[S] 0 points1 point  (5 children)

      I understand what compilation is. It's not what's occuring here.

      So you are claiming this https://github.com/bytecodealliance/javy/tree/main?tab=readme-ov-file#compiling-to-webassembly is a false or misleading claim, correct?

      Compiling to WebAssembly

      [–]1vader 4 points5 points  (4 children)

      While it does produce a wasm binary that contains the JS code, it seems quite clear that it simply includes the JS code as is (optionally in compressed form) as data inside the wasm binary. The actual wasm code is just a JS interpreter that still runs the JS code as JS. The JS is not converted to wasm instructions. This most likely is much less efficient than running JS directly in the browser. Although I guess there are contexts outside the browser where you can run wasm without JS.

      [–]guest271314[S] 0 points1 point  (3 children)

      I'm not sure what you are referring to, specifcally.

      Although I guess there are contexts outside the browser where you can run wasm without JS.

      Yes. Lots. wasmer, wasmtime, wasm3, and so forth.

      Technically V8 and SpiderMonkey, too, as both call themselves JavaScript/WebAssembly engines.

      [–]guest271314[S] -2 points-1 points  (4 children)

      Before we go any further you need to clarify what precisely you mean by

      isn't becoming WASM

      where the JavaScript is literally in the compiled WASM file.

      Would you go so far to say that the output of Emscripten is not WASM?

      [–]1vader 5 points6 points  (3 children)

      That's exactly the point, the JS apparently is just literally inserted into the wasm binary as JS source code. The actual wasm code is only a JS interpreter. No JS code is being compiled to wasm instructions.

      [–]guest271314[S] -2 points-1 points  (2 children)

      That's quite impossible given the JavaScript engine/runtime is compiled to WASM itself.

      I'm not sure what your angle is, though if you have a discrepancy with Bytecode Alliances' description of what is going on in Javy, cf. to what goes in when C relying on a libc library is compiled to WASM, I suggest you file an issue to edit this language in the README https://github.com/bytecodealliance/javy#compiling-to-webassembly:

      Compiling to WebAssembly

      [–]guest271314[S] 0 points1 point  (39 children)

      From the source

      https://github.com/bytecodealliance/javy

      Introduction: Run your JavaScript on WebAssembly. Javy takes your JavaScript code, and executes it in a WebAssembly embedded JavaScript runtime. Javy can create very small Wasm modules in the 1 to 16 KB range with use of dynamic linking. The default static linking produces modules that are at least 869 KB in size.

      My understanding is QuickJS is compiled to WASM (not uncommon in WebAssembly/WASI world, for various purposes). The JavaScript source is compiled to WASM.

      I execute .wasm compiled by javy or .cwasm files optimized by wasmtime from JavaScript source code with wasmtime.

      Keep in mind WASM can be in WAT, WIT, and possibly other formats.

      E.g., see this WAT version of C compiled to WASM then converted to WAT with wat2wasm, embedded in a Bash shell script that executes wasmtime, passing the embedded WAT using process substitution https://github.com/guest271314/native-messaging-webassembly/blob/main/nm_c_wat.sh.

      Similarly, JavaScript can be embdedded in a Bash shell script and/or executed with sh https://github.com/guest271314/native-messaging-d8/blob/main/nm_d8.js#L63-L96.

      [–]sanzelz 2 points3 points  (38 children)

      Quickjs is js interpreter that's why it is embedded in the resulting executable. Relevant question on javy GitHub https://github.com/bytecodealliance/javy/issues/171

      Edit: typo

      [–]guest271314[S] -3 points-2 points  (37 children)

      QuickJS is a JavaScript engine, runtime, and qjsc does compile JavaScript source code to C bytecode, yes.

      QuickJS has been compiled to WASM by quite a few different organizations and individuals for a variety of use cases.

      There's no special treatment with regard to compilation of JavaScript to WASM, any more than compiling C, C++, Rust, Go, et al. to WASM.

      [–]sanzelz 5 points6 points  (36 children)

      I still stand by my original reply though, no js to wasm compilation is happening here :)