Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Ops for decontainerizing if non-rw sub and for type checking return v…
…alues.
  • Loading branch information
jnthn committed Jul 9, 2011
1 parent 1fa3334 commit 2f5b530
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/binder/bind.h
Expand Up @@ -52,7 +52,7 @@ typedef struct {
PMC *sc; /* Serialization context, though we don't care about that here. */
PMC *spill; /* Attribute spill storage. */
PMC *params; /* Array of objects that are all parameters. */
PMC *returns; /* Return type. */
PMC *rtype; /* Return type. */
} Rakudo_Signature;

/* Flags we can set on the Context PMC.
Expand Down
1 change: 1 addition & 0 deletions src/binder/multidispatch.h
Expand Up @@ -12,6 +12,7 @@ typedef struct {
PMC *signature; /* Signature object. */
PMC *dispatchees; /* List of dispatchees, if any. */
PMC *dispatcher_cache; /* Holder for any dispatcher cache. */
INTVAL *rw; /* Is it rw? */
} Rakudo_Code;

/* Represents a candidate. We extract various bits of information about it when
Expand Down
51 changes: 51 additions & 0 deletions src/ops/perl6.ops
Expand Up @@ -663,6 +663,57 @@ inline op perl6_code_object_from_parrot_sub(out PMC, in PMC) :base_core {
}
}

/*

=item perl6_decontainerize_return_value()

If the sub is not rw, decontainerizes the return value.

=cut

*/
inline op perl6_decontainerize_return_value(out PMC, in PMC) :base_core {
if ($2->vtable->base_type == smo_id) {
PMC *cur_ctx = CURRENT_CONTEXT(interp);
PMC *parrot_sub = Parrot_pcc_get_sub(interp, cur_ctx);
PMC *p6sub;
Rakudo_Code *code;
GETATTR_Sub_multi_signature(interp, parrot_sub, p6sub);
code = (Rakudo_Code *)PMC_data(p6sub);
$1 = code->rw ? $2 : Rakudo_cont_decontainerize(interp, $2);
}
else {
$1 = $2;
}
}

/*

=item perl6_type_check_return_value()

Gets the return type for a sub and type checks it.

=cut

*/
inline op perl6_type_check_return_value(in PMC) :base_core {
PMC *cur_ctx = CURRENT_CONTEXT(interp);
PMC *parrot_sub = Parrot_pcc_get_sub(interp, cur_ctx);
PMC *p6sub;
PMC *sig_pmc;
PMC *rtype;
GETATTR_Sub_multi_signature(interp, parrot_sub, p6sub);
sig_pmc = ((Rakudo_Code *)PMC_data(p6sub))->signature;
rtype = ((Rakudo_Signature *)PMC_data(sig_pmc))->rtype;
if (!PMC_IS_NULL(rtype)) {
PMC *decont_value = Rakudo_cont_decontainerize(interp, $1);
if (!STABLE(decont_value)->type_check(interp, decont_value, rtype)) {
/* XXX Awesomize. */
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Type check failed for return value");
}
}
}

/*

Expand Down

0 comments on commit 2f5b530

Please sign in to comment.