{"id":15514685,"url":"https://github.com/fgasper/p5-javascript-quickjs","last_synced_at":"2025-08-22T01:21:21.492Z","repository":{"id":56824522,"uuid":"474436275","full_name":"FGasper/p5-JavaScript-QuickJS","owner":"FGasper","description":"CPAN’s JavaScript::QuickJS","archived":false,"fork":false,"pushed_at":"2024-02-14T18:55:29.000Z","size":252,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T00:51:45.841Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FGasper.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-26T18:41:24.000Z","updated_at":"2024-05-31T20:55:38.000Z","dependencies_parsed_at":"2024-02-11T03:25:23.173Z","dependency_job_id":"7aba7de7-ab73-4e82-b324-6a6eb50f0c56","html_url":"https://github.com/FGasper/p5-JavaScript-QuickJS","commit_stats":{"total_commits":225,"total_committers":2,"mean_commits":112.5,"dds":0.004444444444444473,"last_synced_commit":"9da4d8bb6670c9820a6fd4223f51b173b66602b8"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FGasper%2Fp5-JavaScript-QuickJS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FGasper%2Fp5-JavaScript-QuickJS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FGasper%2Fp5-JavaScript-QuickJS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FGasper%2Fp5-JavaScript-QuickJS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FGasper","download_url":"https://codeload.github.com/FGasper/p5-JavaScript-QuickJS/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248322609,"owners_count":21084336,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T10:00:22.815Z","updated_at":"2025-04-11T00:51:51.276Z","avatar_url":"https://github.com/FGasper.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\nJavaScript::QuickJS - Run JavaScript via [QuickJS](https://bellard.org/quickjs) in Perl\n\n# SYNOPSIS\n\nQuick and dirty …\n\n    my $val = JavaScript::QuickJS-\u003enew()-\u003eeval( q\u003c\n        let foo = \"bar\";\n        [ \"The\", \"last\", \"value\", \"is\", \"returned.\" ];\n    \u003e );\n\n… or load ES6 modules:\n\n    my $js = JavaScript::QuickJS-\u003enew()-\u003ehelpers();\n\n    $js-\u003eeval_module( q/\n        import * as coolStuff from 'cool/stuff';\n\n        for (const [key, value] of Object.entries(coolStuff)) {\n            console.log(key, value);\n        }\n    / );\n\n# DESCRIPTION\n\nThis library embeds Fabrice Bellard’s [QuickJS](https://bellard.org/quickjs)\nengine into a Perl XS module. You can thus run JavaScript\n([ES2020](https://tc39.github.io/ecma262/) specification) directly in your\nPerl programs.\n\nThis distribution includes all needed C code; unlike with most XS modules\nthat interface with C libraries, you don’t need QuickJS pre-installed on\nyour system.\n\n# METHODS\n\n## $obj = _CLASS_-\u003enew( %CONFIG\\_OPTS )\n\nInstantiates _CLASS_. %CONFIG\\_OPTS have the same effect as in\n`configure()` below.\n\n## $obj = _OBJ_-\u003econfigure( %OPTS )\n\nTunes the QuickJS interpreter. Returns _OBJ_.\n\n%OPTS are any of:\n\n- `max_stack_size`\n- `memory_limit`\n- `gc_threshold`\n\nFor more information on these, see QuickJS itself.\n\n## $obj = _OBJ_-\u003eset\\_globals( NAME1 =\u003e VALUE1, .. )\n\nSets 1 or more globals in _OBJ_. See below for details on type conversions\nfrom Perl to JavaScript.\n\nReturns _OBJ_.\n\n## $obj = _OBJ_-\u003ehelpers()\n\nDefines QuickJS’s “helpers”, e.g., `console.log`.\n\nReturns _OBJ_.\n\n## $obj = _OBJ_-\u003estd()\n\nEnables QuickJS’s `std` module and creates a global of the same name\nthat’s usable from both script and module modes.\n\nThis resembles `qjs`’s `--std` flag except that it _only_ enables\n`std`, not `os`.\n\nReturns _OBJ_.\n\n## $obj = _OBJ_-\u003eos()\n\nLike `std()` but enables QuickJS’s `os` module instead of `std`.\n\n## $VALUE = _OBJ_-\u003eeval( $JS\\_CODE )\n\nLike running `qjs -e '...'`. Returns $JS\\_CODE’s last value;\nsee below for details on type conversions from JavaScript to Perl.\n\nUntrapped exceptions in JavaScript will be rethrown as Perl exceptions.\n\n$JS\\_CODE is a _character_ string.\n\n## $promise = _OBJ_-\u003eeval\\_module( $JS\\_CODE )\n\nRuns $JS\\_CODE as a module, which enables ES6 module syntax.\nNote that no values can be returned directly in this mode of execution.\n\nReturns a promise that resolves once the module is loaded.\n\n## $obj = _OBJ_-\u003eawait()\n\nBlocks until all of _OBJ_’s pending work (if any) is complete.\n\nFor example, if you `eval()` some code that creates a promise, call\nthis to wait for that promise to complete.\n\nReturns _OBJ_.\n\n## $obj = _OBJ_-\u003eset\\_module\\_base( $PATH )\n\nSets a base path (a byte string) for ES6 module imports.\n\nReturns _OBJ_.\n\n## $obj = _OBJ_-\u003eunset\\_module\\_base()\n\nRestores QuickJS’s default directory for ES6 module imports\n(as of this writing, it’s the process’s current directory).\n\nReturns _OBJ_.\n\n# TYPE CONVERSION: JAVASCRIPT → PERL\n\nThis module converts returned values from JavaScript thus:\n\n- JS string primitives become _character_ strings in Perl.\n- JS number \u0026 boolean primitives become corresponding Perl values.\n- JS null \u0026 undefined become Perl undef.\n- JS objects …\n    - Arrays become Perl array references.\n    - “Plain” objects become Perl hash references.\n    - Function, RegExp, and Date objects become Perl\n    [JavaScript::QuickJS::Function](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3AFunction), [JavaScript::QuickJS::RegExp](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3ARegExp),\n    and [JavaScript::QuickJS::Date](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3ADate) objects, respectively.\n    - Behaviour is **UNDEFINED** for other object types.\n\n# TYPE CONVERSION: PERL → JAVASCRIPT\n\nGenerally speaking, it’s the inverse of JS → Perl:\n\n- Perl strings, numbers, \u0026 booleans become corresponding JavaScript\nprimitives.\n\n    **IMPORTANT:** Perl versions before 5.36 don’t reliably distinguish “numeric\n    strings” from “numbers”. If your perl predates 5.36, typecast accordingly\n    to prevent your Perl “number” from becoming a JavaScript string. (Even in\n    5.36 and later it’s still a good idea.)\n\n- Perl undef becomes JS null.\n- Unblessed array \u0026 hash references become JavaScript arrays and\n“plain” objects.\n- [Types::Serialiser](https://metacpan.org/pod/Types%3A%3ASerialiser) booleans become JavaScript booleans.\n- Perl code references become JavaScript functions.\n- Perl [JavaScript::QuickJS::Function](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3AFunction), [JavaScript::QuickJS::RegExp](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3ARegExp),\nand [JavaScript::QuickJS::Date](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3ADate) objects become their original\nJavaScript objects.\n- Anything else triggers an exception.\n\n# MEMORY HANDLING NOTES\n\nIf any instance of a class of this distribution is DESTROY()ed at Perl’s\nglobal destruction, we assume that this is a memory leak, and a warning is\nthrown. To prevent this, avoid circular references, and clean up all global\ninstances.\n\nCallbacks make that tricky. When you give a JavaScript function to Perl,\nthat Perl object holds a reference to the QuickJS context. Only once that\nobject is `DESTROY()`ed do we release that QuickJS context reference.\n\nConsider the following:\n\n    my $return;\n\n    $js-\u003eset_globals(  __return =\u003e sub { $return = shift; () } );\n\n    $js-\u003eeval('__return( a =\u003e a )');\n\nThis sets $return to be a [JavaScript::QuickJS::Function](https://metacpan.org/pod/JavaScript%3A%3AQuickJS%3A%3AFunction) instance. That\nobject holds a reference to $js. $js also stores `__return()`,\nwhich is a Perl code reference that closes around $return. Thus, we have\na reference cycle: $return refers to $js, and $js refers to $return. Those\ntwo values will thus leak, and you’ll see a warning about it at Perl’s\nglobal destruction time.\n\nTo break the reference cycle, just do:\n\n    undef $return;\n\n… once you’re done with that variable.\n\nYou _might_ have thought you could instead do:\n\n    $js-\u003eset_globals( __return =\u003e undef )\n\n… but that doesn’t work because $js holds a reference to all Perl code\nreferences it **ever** receives. This is because QuickJS, unlike Perl,\ndoesn’t expose object destructors (`DESTROY()` in Perl), so there’s no\ngood way to release that reference to the code reference.\n\n# CHARACTER ENCODING NOTES\n\nQuickJS (like all JS engines) assumes its strings are text. Since Perl\ncan’t distinguish text from bytes, though, it’s possible to convert\nPerl byte strings to JavaScript strings. It often yields a reasonable\nresult, but not always.\n\nOne place where this falls over, though, is ES6 modules. QuickJS, when\nit loads an ES6 module, decodes that module’s string literals to characters.\nThus, if you pass in byte strings from Perl, QuickJS will treat your\nPerl byte strings’ code points as character code points, and when you\ncombine those code points with those from your ES6 module you may\nget mangled output.\n\nAnother place that may create trouble is if your argument to `eval()`\nor `eval_module()` (above) contains JSON. Perl’s popular JSON encoders\noutput byte strings by default, but as noted above, `eval()` and\n`eval_module()` need _character_ strings. So either configure your\nJSON encoder to output characters, or decode JSON bytes to characters\nbefore calling `eval()`/`eval_module()`.\n\nFor best results, _always_ interact with QuickJS via _character_\nstrings, and double-check that you’re doing it that way consistently.\n\n# NUMERIC PRECISION\n\nNote the following if you expect to deal with “large” numbers:\n\n- JavaScript’s numeric-precision limits apply. (cf.\n[Number.MAX\\_SAFE\\_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER).)\n- Perl’s stringification of numbers may be _less_ precise than\nJavaScript’s storage of those numbers, or even than Perl’s own storage.\nFor example, in Perl 5.34 `print 1000000000000001.0` prints `1e+15`.\n\n    To counteract this loss of precision, add 0 to Perl’s numeric scalars\n    (e.g., `print 0 + 1000000000000001.0`); this will encourage Perl to store\n    numbers as integers when possible, which fixes this precision problem.\n\n- Long-double and quad-math perls may lose precision when converting\nnumbers to/from JavaScript. To see if this affects your perl—which, if\nyou’re unsure, it probably doesn’t—run `perl -V`, and see if that perl’s\ncompile-time options mention long doubles or quad math.\n\n# OS SUPPORT\n\nQuickJS supports Linux, macOS, and Windows natively, so these work without\nissue.\n\nFreeBSD, OpenBSD, \u0026 Cygwin work after a few patches that we apply when\nbuilding this library. (Hopefully these will eventually merge into QuickJS.)\n\n# LIBATOMIC\n\nQuickJS uses C11 atomics. Most platforms implement that functionality in\nhardware, but others (e.g., arm32) don’t. To fill that void, we need to link\nto libatomic.\n\nThis library’s build logic detects whether libatomic is necessary and will\nonly link to it if needed. If, for some reason, you need manual control over\nthat linking, set `JS_QUICKJS_LINK_LIBATOMIC` in the environment to 1 or a\nfalsy value.\n\nIf you don’t know what any of that means, you can probably ignore it.\n\n# SEE ALSO\n\nOther JavaScript modules on CPAN include:\n\n- [JavaScript::Duktape::XS](https://metacpan.org/pod/JavaScript%3A%3ADuktape%3A%3AXS) and [JavaScript::Duktape](https://metacpan.org/pod/JavaScript%3A%3ADuktape) make the\n[Duktape](https://duktape.org) library available to Perl. They’re similar to\nthis library, but Duktape itself (as of this writing) lacks support for\nseveral JavaScript constructs that QuickJS supports. (It’s also slower.)\n- [JavaScript::V8](https://metacpan.org/pod/JavaScript%3A%3AV8) and [JavaScript::V8::XS](https://metacpan.org/pod/JavaScript%3A%3AV8%3A%3AXS) expose Google’s\n[V8](https://v8.dev) library to Perl. Neither seems to support current\nV8 versions.\n- [JE](https://metacpan.org/pod/JE) is a pure-Perl (!) JavaScript engine.\n- [JavaScript](https://metacpan.org/pod/JavaScript) and [JavaScript::Lite](https://metacpan.org/pod/JavaScript%3A%3ALite) expose Mozilla’s\n[SpiderMonkey](https://spidermonkey.dev/) engine to Perl.\n\n# LICENSE \u0026 COPYRIGHT\n\nThis library is copyright 2023 Gasper Software Consulting.\n\nThis library is licensed under the same terms as Perl itself.\nSee [perlartistic](https://metacpan.org/pod/perlartistic).\n\nQuickJS is copyright Fabrice Bellard and Charlie Gordon. It is released\nunder the [MIT license](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgasper%2Fp5-javascript-quickjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffgasper%2Fp5-javascript-quickjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgasper%2Fp5-javascript-quickjs/lists"}