Skip to content
Permalink
Browse files

[js] Add support to the rakudo-library for running rakudo while captu…

…ring stderr/stdin/status

While be used to fake is_run in the browser
  • Loading branch information...
pmurias committed Nov 12, 2018
1 parent 1865db0 commit fdd249a38890cd0248ac1abb95a56232256d5d70
Showing with 94 additions and 1 deletion.
  1. +94 −1 src/vm/js/rakudo-library.js
@@ -24,7 +24,7 @@ const code = require('./rakudo.js');

const core = require('nqp-runtime/core.js');

module.exports = function(source, options = {}) {
module.exports.compile = function(source, options = {}) {
const tmpFile = tmp.tmpNameSync();

passedArgs = ['perl6-js', '--output', tmpFile, '--target=js', source];
@@ -63,3 +63,96 @@ module.exports = function(source, options = {}) {

return {js: fs.readFileSync(tmpFile, 'utf8'), loaded: loaded};
};

module.exports.capturedRun = function(source, input, compileArgs, args) {
const out = [];
const err = [];

passedArgs = ['perl6-js'].concat(compileArgs, ['*SOURCE*'], args);

const oldExit = nqp.op.exit;

class Exit {
constructor(status) {
this.status = status;
}
}

nqp.op.exit = function(status) {
throw new Exit(status);
};

const oldStdoutWritefh = nqp.op.getstdout().constructor.prototype.$$writefh;
nqp.op.getstdout().constructor.prototype.$$writefh = function(buf) {
out.push(core.toRawBuffer(buf));
}

const oldStderrWritefh = nqp.op.getstderr().constructor.prototype.$$writefh;
nqp.op.getstderr().constructor.prototype.$$writefh = function(buf) {
err.push(core.toRawBuffer(buf));
}

const oldOpen = nqp.op.open;

class SourceFileHandle {
constructor(source) {
this.source = Buffer.from(source, 'utf8');
}

$$readfh(buf, bytes) {
core.writeBuffer(buf, this.source.slice(0, bytes));
this.source = this.source.slice(bytes);
return buf;
}

$$closefh() {
}
};

nqp.op.open = function(name, mode) {
if (name === '*SOURCE*') {
return new SourceFileHandle(source);
} else {
return oldOpen(name, mode);
}
};

const oldStat = nqp.op.stat;

const EXISTS = 0;
const ISDIR = 2;

nqp.op.stat = function(file, code) {
if (file === '*SOURCE*' && code === EXISTS) {
return 1;
} else if (file === '*SOURCE*' && code === ISDIR) {
return 0;
} else {
return oldStat(file, code);
}
};

let status = 0;

try {
code();
} catch (e) {
if (e instanceof Exit) {
status = e.status;
} else {
throw e;
}
}

nqp.op.getstdout().constructor.prototype.$$writefh = oldStdoutWritefh;
nqp.op.getstderr().constructor.prototype.$$writefh = oldStderrWritefh;

nqp.op.exit = oldExit;
nqp.op.open = oldOpen;

return {
status: status,
out: Buffer.concat(out).toString(),
err: Buffer.concat(err).toString()
};
};

0 comments on commit fdd249a

Please sign in to comment.
You can’t perform that action at this time.