NAME

JavaScript::QuickJS - Run JavaScript via QuickJS in Perl

SYNOPSIS

Quick and dirty …

my $val = JavaScript::QuickJS->new()->eval( q<
    let foo = "bar";
    [ "The", "last", "value", "is", "returned." ];
> );

DESCRIPTION

This library embeds Fabrice Bellard’s QuickJS engine into a Perl XS module. You can thus run JavaScript (ES2020 specification) directly in your Perl programs.

This distribution includes all needed C code; unlike with most XS modules that interface with C libraries, you don’t need QuickJS pre-installed on your system.

METHODS

$obj = CLASS->new()

Instantiates CLASS.

$obj = OBJ->set_globals( NAME1 => VALUE1, .. )

Sets 1 or more globals in OBJ. See below for details on type conversions from Perl to JavaScript.

$obj = OBJ->helpers()

Defines QuickJS’s “helpers”, e.g., console.log.

$obj = OBJ->std()

Enables (but does not import) QuickJS’s std module.

$obj = OBJ->os()

Like std() but for QuickJS’s os module.

$VALUE = OBJ->eval( $JS_CODE )

Comparable to running qjs -e '...'. Returns the last value from $JS_CODE; see below for details on type conversions from JavaScript to Perl.

Untrapped exceptions in JavaScript will be rethrown as Perl exceptions.

OBJ->eval_module( $JS_CODE )

Runs $JS_CODE as a module, which enables ES6 module syntax. Note that no values can be returned directly in this mode of execution.

$obj = OBJ->set_module_base( $PATH )

Sets a base path (a byte string) for ES6 module imports.

$obj = OBJ->unset_module_base()

Restores QuickJS’s default directory for ES6 module imports (as of this writing, it’s the process’s current directory).

TYPE CONVERSION: JAVASCRIPT → PERL

This module converts returned values from JavaScript thus:

  • JS string primitives become character strings in Perl.

  • JS number & boolean primitives become corresponding Perl values.

  • JS null & undefined become Perl undef.

  • JS objects …

    • Arrays become Perl array references.

    • “Plain” objects become Perl hash references.

    • Functions become Perl code references.

    • Behaviour is UNDEFINED for other object types.

TYPE CONVERSION: PERL → JAVASCRIPT

Generally speaking, it’s the inverse of JS → Perl, though since Perl doesn’t differentiate “numeric strings” from “numbers” there’s occasional ambiguity. In such cases, behavior is undefined; be sure to typecast in JavaScript accordingly.

  • Perl strings, numbers, & booleans become corresponding JavaScript primitives.

  • Perl undef becomes JS null.

  • Unblessed array & hash references become JavaScript arrays and “plain” objects.

  • Perl code references become JavaScript functions.

  • Anything else triggers an exception.

NUMERIC PRECISION

Note the following if you expect to deal with “large” numbers:

  • JavaScript’s numeric-precision limits apply. (cf. Number.MAX_SAFE_INTEGER.)

  • Perl’s stringification of numbers may be less precise than JavaScript’s storage of those numbers, or even than Perl’s own storage. For example, in Perl 5.34 print 1000000000000001.0 prints 1e+15.

    To counteract this loss of precision, add 0 to Perl’s numeric scalars (e.g., print 0 + 1000000000000001.0); this will encourage Perl to store numbers as integers when possible, which fixes the precision problem.

  • Long-double and quad-math perls may lose precision when converting numbers to/from JavaScript. To see if this affects your perl—which, if you’re unsure, it probably doesn’t—run perl -V, and see if the compile-time options mention long doubles or quad math.

OS SUPPORT

QuickJS supports Linux & macOS natively, so these work without issue.

FreeBSD, OpenBSD, & Cygwin work after a few patches that we apply when building this library. (Hopefully these will eventually merge into QuickJS.)

SEE ALSO

Other JavaScript modules on CPAN include:

LICENSE & COPYRIGHT

Copyright 2022 Gasper Software Consulting.

This library is licensed under the same terms as Perl itself. See perlartistic.