FGasper/p5-JavaScript-QuickJS

`--std` versus `->std()`

Closed this issue · 7 comments

I use a javascript program abc2svg that I call using a wrapper script chordproabc.js. This works fine:

$ qjs --std chordproabc.js lib/abc2svg foo.html foo.abc

Unlike the qjs --std option, the JavaScript::QuickJS std() method enables but does not import. So I add two import lines

import * as std from 'std'
import * as os  from 'os'

Now the script fails somewhere in the guts of abc2svg. It doesn't matter whether I import something or everything from std or os, as soon as I have an import it fails.

Much to my surprise this is reproducible with qjs, when I invoke the script with the imports:

$ qjs --std chordproabc.js lib/abc2svg foo.html foo.abc
TypeError: not a function
    at abc_cmd (lib/abc2svg/cmdline.js:148)
    at <anonymous> (chordproabc.js:77)

I don't have a clue what is going on but it must be related to the difference between --std and ->std(). What is the reason to make these different?

I've attached a zip with the necessary files to reproduce this.
qq.zip

UPDATE: Same failure with quickjs-ng.

qjs will, by default, detect whether the executed file—in your case, chordproabc.js—is a module or a script. By adding the import statements you’re subtly making qjs parse your file as an ES6 module, which means that var abc2svg is no longer global. Thus, loadjs is the no-op function in abc2svg-1.js, not the “useful” one in chordproabc.js.

You can mitigate this by doing globalThis.abc2svg = { … in chordproabc.js, but I think globalThis is an implementation detail of QuickJS and likely not something to depend on.

Really, I think it’s an oversight that std and os are only available to modules and not plain scripts. That said, it should be fairly easy to accommodate in your code by just doing a dynamic import, e.g., import('std')->then( std => { … } ).

Interesting. How does globalThis relate to the set_globals() function?

For the embedding, I would like to replace the chordproabc.js script by perl code. Can you shed some light?
Thanks!
qq2.zip

How does globalThis relate to the set_globals() function?

TBH I’m not sure … play around with it?

I would like to replace the chordproabc.js script by perl code. Can you shed some light?

Looks like you’re on the right path.

Succes! Thanks!

What would be required for a switch to quickjs-ng?

jsq.pl.txt

What would be required for a switch to quickjs-ng?

I haven’t looked at qjs-ng, but in theory, it should be as simple as just swapping out the repos.

If you look, you’ll see that I’ve applied a couple of quickjs patches in this project: a couple in git, and a few more via Makefile.PL. Ideally, those should all be upstream before any switchover.

I’ve pushed version 0.19, which matches qjs’s behaviour in creating std (and os) globals.

By odd coincidence, Fabrice merged some patches today—the first quickjs updates in almost 2 years. One of them fixes a CVE, so you should update.

For the record, globalThis is actually the standardised works everywhere version of what window/document/et. al. were in browser contexts.

(apologies for thread necro but it seemed worth leaving here as a note)