nodeprof.js icon indicating copy to clipboard operation
nodeprof.js copied to clipboard

Instrumenting ES6 code

Open mwaldrich opened this issue 5 years ago • 1 comments

Is it currently possible to instrument ES6 code using mx? I know both NodeProf and GraalJS support ES6, but I'm not sure how to actually achieve this with mx.

Here's an example:

one.js

import { add } from "./two";

console.log(add(1, 2));

two.js

function add(x, y) {
    return x + y;
}

export { add };

Execution

❯ mx jalangi --analysis ./src/ch.usi.inf.nodeprof/js/analysis/trivial/emptyTemplate.js one.js
<function>:1
import { add } from "./two";
^

SyntaxError: Expected an operand but found import
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.<anonymous> (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function._load (internal/modules/cjs/loader.js:585:3)
    at Function.runMain (internal/modules/cjs/loader.js:831:12)
    at Object.<anonymous> (/home/mwaldrich/tmp/19-06-27-nodeprof-expr/19-02-21-clean/workspace-nodeprof/nodeprof.js/src/ch.usi.inf.nodeprof/js/jalangi.js:251:19)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.<anonymous> (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)

GraalJS argument

I also found this page in the GraalJS docs that show the js.ecmascript-version argument. I tried using this with mx, but it didn't help.

❯ mx jalangi --analysis ./src/ch.usi.inf.nodeprof/js/analysis/trivial/emptyTemplate.js one.js --js.ecmascript-version=6
<function>:1
import { add } from "./two";
^

SyntaxError: Expected an operand but found import
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.<anonymous> (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function._load (internal/modules/cjs/loader.js:585:3)
    at Function.runMain (internal/modules/cjs/loader.js:831:12)
    at Object.<anonymous> (/home/mwaldrich/tmp/19-06-27-nodeprof-expr/19-02-21-clean/workspace-nodeprof/nodeprof.js/src/ch.usi.inf.nodeprof/js/jalangi.js:251:19)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.<anonymous> (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)

mwaldrich avatar Sep 26 '19 16:09 mwaldrich

mx jalangi uses node as the entrypoint for execution (note there is a difference in GraalVM between running pure JS mx js and Node mx node), thus you need to enable experimental support for ES modules in Node.js with an option (also in Node 10.x files must end with .mjs): https://nodejs.org/docs/latest-v10.x/api/esm.html

mx jalangi currently does not pass through node command line options, but you can inject them yourself.

To see what's happening under the hood run mx -v jalangi --analysis foo.js bar.mjs You'll see the last line starts with env:

env MX_SUBPROCESS_COMMAND_FILE <...> <path>/Release/node --jvm --vm.ea --experimental-options --engine.InstrumentExceptionsAreThrown=true --nodeprof <...> --analysis foo.js bar.mjs

Copy that line and inject --experimental-modules before the jalangi.js script:

env MX_SUBPROCESS_COMMAND_FILE <...> <path>/Release/node --jvm --vm.ea --experimental-options --engine.InstrumentExceptionsAreThrown=true --experimental-modules --nodeprof <...> --analysis foo.js bar.mjs

alexjordan avatar Sep 26 '19 22:09 alexjordan