Skip to content

Commit

Permalink
Implement checking post constraints.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Jul 2, 2013
1 parent 54b7dd5 commit dceb13c
Showing 1 changed file with 49 additions and 1 deletion.
50 changes: 49 additions & 1 deletion src/vm/jvm/runtime/org/perl6/rakudo/Binder.java
Expand Up @@ -182,6 +182,14 @@ private static int juncOrFail(ThreadContext tc, Ops.GlobalExt gcx, SixModelObjec
/* Binds a single argument into the lexpad, after doing any checks that are
* needed. Also handles any type captures. If there is a sub signature, then
* re-enters the binder. Returns one of the BIND_RESULT_* codes. */
private static final CallSiteDescriptor ACCEPTS_o = new CallSiteDescriptor(
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ }, null);
private static final CallSiteDescriptor ACCEPTS_i = new CallSiteDescriptor(
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_INT }, null);
private static final CallSiteDescriptor ACCEPTS_n = new CallSiteDescriptor(
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_NUM }, null);
private static final CallSiteDescriptor ACCEPTS_s = new CallSiteDescriptor(
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_STR }, null);
private static int bindOneParam(ThreadContext tc, Ops.GlobalExt gcx, CallFrame cf, SixModelObject param,
Object origArg, byte origFlag, boolean noNomTypeCheck, String[] error) {
/* Get parameter flags and variable name. */
Expand Down Expand Up @@ -436,7 +444,47 @@ else if ((paramFlags & SIG_ELEM_HASH_SIGIL) != 0) {
if ((paramFlags & SIG_ELEM_INVOCANT) != 0)
cf.oLex[sci.oTryGetLexicalIdx("self")] = decontValue;

/* TODO: post_constraints. */
/* Handle any constraint types (note that they may refer to the parameter by
* name, so we need to have bound it already). */
SixModelObject postConstraints = param.get_attribute_boxed(tc, gcx.Parameter,
"$!post_contraints", HINT_post_constraints);
if (postConstraints != null) {
long numConstraints = postConstraints.elems(tc);
for (long i = 0; i < numConstraints; i++) {
/* Check we meet the constraint. */
SixModelObject consType = postConstraints.at_pos_boxed(tc, i);
SixModelObject acceptsMeth = org.perl6.nqp.runtime.Ops.findmethod(consType, "ACCEPTS", tc);

/*if (STABLE(cons_type)->type_check(interp, cons_type, code_type))
Parrot_sub_capture_lex(interp,
VTABLE_get_attr_keyed(interp, cons_type, code_type, DO_str));*/
switch (flag) {
case CallSiteDescriptor.ARG_INT:
org.perl6.nqp.runtime.Ops.invokeDirect(tc, acceptsMeth,
ACCEPTS_i, new Object[] { consType, arg_i });
break;
case CallSiteDescriptor.ARG_NUM:
org.perl6.nqp.runtime.Ops.invokeDirect(tc, acceptsMeth,
ACCEPTS_n, new Object[] { consType, arg_n });
break;
case CallSiteDescriptor.ARG_STR:
org.perl6.nqp.runtime.Ops.invokeDirect(tc, acceptsMeth,
ACCEPTS_s, new Object[] { consType, arg_s });
break;
default:
org.perl6.nqp.runtime.Ops.invokeDirect(tc, acceptsMeth,
ACCEPTS_o, new Object[] { consType, arg_o });
break;
}
long result = org.perl6.nqp.runtime.Ops.istrue(
org.perl6.nqp.runtime.Ops.result_o(tc.curFrame), tc);
if (result == 0) {
if (error != null)
error[0] = "Constraint type check failed for parameter '" + varName + "'";
return BIND_RESULT_FAIL;
}
}
}

/* TODO: attributives. */
if ((paramFlags & SIG_ELEM_BIND_ATTRIBUTIVE) != 0) {
Expand Down

0 comments on commit dceb13c

Please sign in to comment.