Skip to content
Permalink
Browse files

[js] Sprinkle async/await on nqp::p6... ops

  • Loading branch information...
pmurias committed Dec 8, 2018
1 parent 8b13655 commit 2869a48b1f976ada1375a167e85e6338f4f2d863
Showing with 49 additions and 49 deletions.
  1. +14 −14 src/vm/js/Perl6/Ops.nqp
  2. +1 −1 src/vm/js/perl6-runtime/package.json
  3. +30 −30 src/vm/js/perl6-runtime/runtime.js
  4. +4 −4 src/vm/js/rakudo-library.js
@@ -11,7 +11,7 @@ register_op_desugar('', -> $qast {
QAST::Op.new(:op('null'));
});

$ops.add_simple_op('p6sink', $ops.VOID, [$ops.OBJ], :ctx, :side_effects);
$ops.add_simple_op('p6sink', $ops.VOID, [$ops.OBJ], :ctx, :side_effects, :await);

$ops.add_simple_op('p6reprname', $ops.OBJ, [$ops.OBJ], :decont(0));

@@ -59,40 +59,40 @@ $ops.add_op('p6bindsig', :!inlinable, sub ($comp, $node, :$want) {
my $ops := nqp::getcomp('QAST').operations;
my $tmp := $*BLOCK.add_tmp;
$ops.new_chunk($ops.VOID, "", [
"$tmp = nqp.p6binder.bind_sig($*CTX, null, nqp.p6binder, nqp.op.savecapture(Array.prototype.slice.call(arguments)));\n",
"$tmp = /*await*/ nqp.p6binder.bind_sig($*CTX, null, nqp.p6binder, nqp.op.savecapture(Array.prototype.slice.call(arguments)));\n",
"if ($tmp !== nqp.Null) return $tmp;\n"
]);
});

$ops.add_simple_op('p6configposbindfailover', $ops.VOID, [$ops.OBJ, $ops.OBJ], sub ($pos, $pos_bind_failover) {
"nqp.p6binder.set_pos_bind_failover($*CTX, null, nqp.p6binder, $pos, $pos_bind_failover)"
"/*await*/ nqp.p6binder.set_pos_bind_failover($*CTX, null, nqp.p6binder, $pos, $pos_bind_failover)"
}, :side_effects);

$ops.add_simple_op('p6setautothreader', $ops.VOID, [$ops.OBJ], sub ($autothreader) {
"nqp.p6binder.set_autothreader($*CTX, null, nqp.p6binder, $autothreader)"
"/*await*/ nqp.p6binder.set_autothreader($*CTX, null, nqp.p6binder, $autothreader)"
}, :side_effects);

$ops.add_simple_op('p6trialbind', $ops.OBJ, [$ops.OBJ, $ops.OBJ, $ops.OBJ], :!inlinable, sub ($sig, $args, $sig_flags) {
"nqp.p6binder.trial_bind($*CTX, null, nqp.p6binder, $sig, $args, $sig_flags)"
"/*await*/ nqp.p6binder.trial_bind($*CTX, null, nqp.p6binder, $sig, $args, $sig_flags)"
});

$ops.add_simple_op('p6isbindable', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :!inlinable, sub ($sig, $cap) {
"nqp.retval(HLL, nqp.p6binder.is_bindable($*CTX, null, nqp.p6binder, $sig, $cap))"
"nqp.retval(HLL, /*await*/ nqp.p6binder.is_bindable($*CTX, null, nqp.p6binder, $sig, $cap))"
});

$ops.add_simple_op('p6bindcaptosig', $ops.OBJ, [$ops.OBJ, $ops.OBJ], sub ($sig, $cap) {
"nqp.p6binder.bind_cap_to_sig($*CTX, null, nqp.p6binder, $sig, $cap)"
"/*await*/ nqp.p6binder.bind_cap_to_sig($*CTX, null, nqp.p6binder, $sig, $cap)"
}, :side_effects);

$ops.add_op('p6bindattrinvres', $ops.bindattr($ops.OBJ, :inverted_result));

$ops.add_simple_op('p6invokeunder', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :side_effects, :ctx, :takes_hll);
$ops.add_simple_op('p6invokeunder', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :side_effects, :ctx, :takes_hll, :await);

$ops.add_simple_op('p6settypes', $ops.OBJ, [$ops.OBJ], :side_effects);
$ops.add_simple_op('p6init', $ops.OBJ, [], :side_effects, -> {"nqp.extraRuntime('perl6', {$ops.quote_string($*PERL6_RUNTIME)})"});
$ops.add_simple_op('p6bool', $ops.OBJ, [$ops.BOOL], :side_effects);

$ops.add_simple_op('p6typecheckrv', $ops.OBJ, [$ops.OBJ, $ops.OBJ, $ops.OBJ], :ctx);
$ops.add_simple_op('p6typecheckrv', $ops.OBJ, [$ops.OBJ, $ops.OBJ, $ops.OBJ], :ctx, :await);

$ops.add_simple_op('p6definite', $ops.OBJ, [$ops.OBJ], :decont(0));

@@ -107,11 +107,11 @@ $ops.add_simple_op('p6capturelexwhere', $ops.OBJ, [$ops.OBJ], :side_effects, sub
"nqp.op.p6capturelexwhere({$*BLOCK.ctx}, $codeObj)"
});

$ops.add_simple_op('p6bindassert', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects);
$ops.add_simple_op('p6store', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects);
$ops.add_simple_op('p6bindassert', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects, :await);
$ops.add_simple_op('p6store', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects, :await);

$ops.add_simple_op('p6argvmarray', $ops.OBJ, [], :side_effects, sub () {
"nqp.op.p6argvmarray($*CTX, Array.prototype.slice.call(arguments))"
"/*await*/ nqp.op.p6argvmarray($*CTX, Array.prototype.slice.call(arguments))"
});

$ops.add_simple_op('p6stateinit', $ops.INT, [], sub () {
@@ -155,7 +155,7 @@ $ops.add_op('p6decontrv', :!inlinable, sub ($comp, $node, :$want) {
$ops.add_simple_op('p6decodelocaltime', $ops.OBJ, [$ops.INT], :side_effects); # TODO not really :side_effects just needs marking as returning a fresh value

$ops.add_simple_op('p6finddispatcher', $ops.OBJ, [$ops.STR], :side_effects, sub ($usage) {
"nqp.op.p6finddispatcher({$*BLOCK.ctx}, $usage)"
"/*await*/ nqp.op.p6finddispatcher({$*BLOCK.ctx}, $usage)"
});


@@ -174,4 +174,4 @@ $ops.add_simple_op('p6getouterctx', $ops.OBJ, [$ops.OBJ], :decont(0), :!inlinabl

$ops.add_simple_op('p6staticouter', $ops.OBJ, [$ops.OBJ], :ctx, :side_effects);

$ops.add_simple_op('p6fakerun', $ops.OBJ, [$ops.OBJ], :side_effects, :takes_hll);
$ops.add_simple_op('p6fakerun', $ops.OBJ, [$ops.OBJ], :side_effects, :takes_hll, :await);
@@ -1,6 +1,6 @@
{
"name": "perl6-runtime",
"version": "0.17.0",
"version": "0.28.0",
"description": "the runtime for the js backend for rakudo",
"bugs": {
"email": "pawelmurias@gmail.com"
@@ -34,37 +34,37 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
return (obj === Null || obj.typeObject_) ? False : True;
};

op.p6typecheckrv = function(ctx, rv, routine, bypassType) {
op.p6typecheckrv = /*async*/ function(ctx, rv, routine, bypassType) {
const sig = routine.$$getattr(Code, '$!signature');
let rtype = sig.$$getattr(Signature, '$!returns');
if (rtype !== Null && nqp.op.objprimspec(rtype) === 0) {
let targetType;
const how = rtype._STable.HOW;
const archetypes = how.archetypes(ctx, null, how);
const isCoercive = nqp.retval_bool(ctx, archetypes.coercive(ctx, null, archetypes));
const archetypes = /*await*/ how.archetypes(ctx, null, how);
const isCoercive = nqp.retval_bool(ctx, /*await*/ archetypes.coercive(ctx, null, archetypes));

if (isCoercive) {
targetType = how.target_type(ctx, null, how, rtype);
rtype = how.constraint_type(ctx, null, how, rtype);
targetType = /*await*/ how.target_type(ctx, null, how, rtype);
rtype = /*await*/ how.constraint_type(ctx, null, how, rtype);
}

const decontValue = rv.$$decont(ctx);
if (decontValue.$$istype(ctx, rtype) === 0 && decontValue.$$istype(ctx, bypassType) === 0) {
const decontValue = /*await*/ rv.$$decont(ctx);
if (/*await*/ decontValue.$$istype(ctx, rtype) === 0 && /*await*/ decontValue.$$istype(ctx, bypassType) === 0) {
const thrower = getThrower("X::TypeCheck::Return");
if (thrower === Null) {
ctx.die("Type check failed for return value");
/*await*/ ctx.die("Type check failed for return value");
} else {
thrower.$$call(ctx, null, decontValue, rtype);
/*await*/ thrower.$$call(ctx, null, decontValue, rtype);
}
}

if (targetType !== undefined && targetType !== rtype) {
const targetTypeName = targetType._STable.HOW.name(
const targetTypeName = /*await*/ targetType._STable.HOW.name(
ctx, null, targetType._STable.HOW, targetType).$$getStr();
if (rv.$$can(ctx, targetTypeName)) {
if (/*await*/ rv.$$can(ctx, targetTypeName)) {
return rv[targetTypeName](ctx, null, rv);
} else {
const rtypeName = rtype._STable.HOW.name(ctx, null, rtype._STable.HOW, rtype).$$getStr();
const rtypeName = /*await*/ rtype._STable.HOW.name(ctx, null, rtype._STable.HOW, rtype).$$getStr();
throw new nqp.NQPException(
`Unable to coerce the return value from ${rtypeName} to ${targetTypeName} ;` +
`no coercion method defined`);
@@ -174,40 +174,40 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
return codeObj;
};

op.p6bindassert = function(ctx, value, type) {
op.p6bindassert = /*async*/ function(ctx, value, type) {
if (type !== Mu) {
if (value.$$decont(ctx).$$istype(ctx, type) == 0) {
if (/*await*/ value.$$decont(ctx).$$istype(ctx, type) == 0) {
const thrower = getThrower("X::TypeCheck::Binding");

if (thrower === null) {
ctx.die("Type check failed in binding");
/*await*/ ctx.die("Type check failed in binding");
} else {
thrower.$$call(ctx, null, value, type);
/*await*/ thrower.$$call(ctx, null, value, type);
}
}
}
return value;
};

op.p6store = function(ctx, cont, value) {
op.p6store = /*async*/ function(ctx, cont, value) {
if (cont.$$assign) {
cont.$$assign(ctx, value.$$decont(ctx));
/*await*/ cont.$$assign(ctx, value.$$decont(ctx));
} else {
if (!cont.STORE) {
// TODO throw typed exception X::Assignment::RO
ctx.die("Cannot assign to a non-container");
} else {
cont.STORE(ctx, null, cont, value);
/*await*/ cont.STORE(ctx, null, cont, value);
}
}
return cont;
};


op.p6argvmarray = function(ctx, args) {
op.p6argvmarray = /*async*/ function(ctx, args) {
const array = [];
for (let i=2; i < args.length; i++) {
array[i-2] = nqp.op.hllizefor(ctx, nqp.arg(nqp.getHLL('perl6'), args[i]), 'perl6');
array[i-2] = /*await*/ nqp.op.hllizefor(ctx, nqp.arg(nqp.getHLL('perl6'), args[i]), 'perl6');
}
return nqp.createArray(array);
};
@@ -225,15 +225,15 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
]);
}

op.p6finddispatcher = function(ctx, usage) {
op.p6finddispatcher = /*async*/ function(ctx, usage) {
let dispatcher;
let search = ctx.$$caller;
while (search) {
/* Do we have a dispatcher here? */
if (search.hasOwnProperty("$*DISPATCHER") && search["$*DISPATCHER"] !== Null) {
dispatcher = search["$*DISPATCHER"];
if (dispatcher.typeObject_) {
dispatcher = dispatcher.vivify_for(ctx, null, dispatcher, search.codeRef().codeObj, search, new Capture(search.$$args[1], Array.prototype.slice.call(search.$$args, 2)));
dispatcher = /*await*/ dispatcher.vivify_for(ctx, null, dispatcher, search.codeRef().codeObj, search, new Capture(search.$$args[1], Array.prototype.slice.call(search.$$args, 2)));
search["$*DISPATCHER"] = dispatcher;
}
return dispatcher;
@@ -243,9 +243,9 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {

const thrower = getThrower("X::NoDispatcher");
if (thrower === Null) {
ctx.die(usage + ' is not in the dynamic scope of a dispatcher');
/*await*/ ctx.die(usage + ' is not in the dynamic scope of a dispatcher');
} else {
thrower.$$call(ctx, null, new nqp.NativeStrArg(usage));
/*await*/ thrower.$$call(ctx, null, new nqp.NativeStrArg(usage));
}

};
@@ -263,7 +263,7 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
throw 'Could not find arguments for dispatcher';
};

op.p6sink = function(ctx, obj) {
op.p6sink = /*async*/ function(ctx, obj) {
if (obj.typeObject_ || obj === Null) return;
if (obj.$$can(ctx, 'sink')) {
obj.sink(ctx, null, obj);
@@ -291,14 +291,14 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
return closure.outerCtx || Null;
};

op.p6invokeunder = function(ctx, currentHLL, fake, code) {
op.p6invokeunder = /*async*/ function(ctx, currentHLL, fake, code) {
const spec = fake._STable.invocationSpec;

const fakeCode = fake.$$getattr(spec.classHandle, spec.attrName);

const invokingUnder = new nqp.Ctx(ctx, fakeCode.outerCtx, fakeCode);

return nqp.retval(currentHLL, code.$$call(invokingUnder, null));
return nqp.retval(currentHLL, /*await*/ code.$$call(invokingUnder, null));

};

@@ -344,11 +344,11 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
const store_unchecked = this.store_unchecked;

this.STable.addInternalMethod('$$assignunchecked', function(ctx, value) {
store_unchecked.$$call(ctx, null, this, value);
return store_unchecked.$$call(ctx, null, this, value);
});

this.STable.addInternalMethod('$$assign', function(ctx, value) {
store.$$call(ctx, null, this, value);
return store.$$call(ctx, null, this, value);
});

this.STable.addInternalMethod('$$decont', function(ctx) {
@@ -9,8 +9,8 @@ function fakeArgs(isMain) {
};


const code = function() {
require('./rakudo.js')(nqp, true);
const code = /*async*/ function() {
/*await*/ require('./rakudo.js')(nqp, true);
};

const core = require('nqp-runtime/core.js');
@@ -69,7 +69,7 @@ module.exports.compile = function(source, options = {}) {
return {js: fs.readFileSync(tmpFile, 'utf8'), loaded: loaded};
};

module.exports.capturedRun = function(source, input, compileArgs, args, passedEnv) {
module.exports.capturedRun = /*await*/ function(source, input, compileArgs, args, passedEnv) {
const oldGlobalContext = nqp.freshGlobalContext();

const env = nqp.hash();
@@ -163,7 +163,7 @@ module.exports.capturedRun = function(source, input, compileArgs, args, passedEn
let status = 0;

try {
code();
/*await*/ code();
} catch (e) {
if (e instanceof Exit) {
status = e.status;

0 comments on commit 2869a48

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