Skip to content

Commit

Permalink
[js] Make nqp::p6typecheckrv do type coercions when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
pmurias committed Dec 30, 2017
1 parent 3b453c5 commit 0a42502
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion src/vm/js/perl6-runtime/runtime.js
Expand Up @@ -44,8 +44,18 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {

op.p6typecheckrv = function(ctx, rv, routine, bypassType) {
const sig = routine.$$getattr(Code, '$!signature');
const rtype = sig.$$getattr(Signature, '$!returns');
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 = archetypes.coercive(ctx, null, archetypes).$$toBool(ctx);

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

const decontValue = rv.$$decont(ctx);
if (decontValue.$$istype(ctx, rtype) === 0 && decontValue.$$istype(ctx, bypassType) === 0) {
const thrower = getThrower("X::TypeCheck::Return");
Expand All @@ -55,6 +65,19 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
thrower.$$call(ctx, null, decontValue, rtype);
}
}

if (targetType !== undefined && targetType !== rtype) {
const targetTypeName = targetType._STable.HOW.name(
ctx, null, targetType._STable.HOW, targetType).$$getStr();
if (rv.$$can(ctx, targetTypeName)) {
return rv[targetTypeName](ctx, null, rv);
} else {
const rtypeName = 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`);
}
}
}

return rv;
Expand Down

0 comments on commit 0a42502

Please sign in to comment.