Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move throwing of X::TypeCheck::Binding out of bindOneParam.
Previously we'd fail with "Nominal type check failed for parameter 'null'", in
e.g. <sub f($) { }; f Junction>, because we threw the Exception directly. This
patch moves the throw *after* actually failing to bind.
  • Loading branch information
peschwa committed Oct 30, 2015
1 parent 3b212a0 commit fe5b300
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
19 changes: 10 additions & 9 deletions src/vm/jvm/runtime/org/perl6/rakudo/Binder.java
Expand Up @@ -139,7 +139,7 @@ public static void bindTypeCaptures(ThreadContext tc, SixModelObject typeCaps, C

/* Assigns an attributive parameter to the desired attribute. */
private static int assignAttributive(ThreadContext tc, CallFrame cf, String varName,
int paramFlags, SixModelObject attrPackage, SixModelObject value, String[] error) {
int paramFlags, SixModelObject attrPackage, SixModelObject value, Object[] error) {
/* Find self. */
StaticCodeInfo sci = cf.codeRef.staticInfo;
Integer selfIdx = sci.oTryGetLexicalIdx("self");
Expand Down Expand Up @@ -191,7 +191,7 @@ private static int juncOrFail(ThreadContext tc, RakOps.GlobalExt gcx, SixModelOb
private static final CallSiteDescriptor bindThrower = new CallSiteDescriptor(
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_STR }, null);
private static int bindOneParam(ThreadContext tc, RakOps.GlobalExt gcx, CallFrame cf, SixModelObject param,
Object origArg, byte origFlag, boolean noNomTypeCheck, String[] error) {
Object origArg, byte origFlag, boolean noNomTypeCheck, Object[] error) {
/* Get parameter flags and variable name. */
param.get_attribute_native(tc, gcx.Parameter, "$!flags", HINT_flags);
int paramFlags = (int)tc.native_i;
Expand All @@ -211,7 +211,7 @@ private static int bindOneParam(ThreadContext tc, RakOps.GlobalExt gcx, CallFram
/* Check if boxed/unboxed expections are met. */
int desiredNative = paramFlags & SIG_ELEM_NATIVE_VALUE;
boolean is_rw = (paramFlags & SIG_ELEM_IS_RW) != 0;
int gotNative = origFlag & 7;
int gotNative = origFlag & (CallSiteDescriptor.ARG_INT | CallSiteDescriptor.ARG_NUM | CallSiteDescriptor.ARG_STR);
if (is_rw && desiredNative != 0) {
switch (desiredNative) {
case SIG_ELEM_NATIVE_INT_VALUE:
Expand Down Expand Up @@ -369,15 +369,16 @@ else if (desiredNative == 0) {
if (error != null) {

SixModelObject thrower = RakOps.getThrower(tc, "X::TypeCheck::Binding");
if (thrower != null && decontValue.st.WHAT != gcx.Junction) {
Ops.invokeDirect(tc, thrower,
bindThrower, new Object[] { decontValue.st.WHAT, nomType.st.WHAT, varName });
return BIND_RESULT_FAIL;
if (thrower != null) {
error[0] = thrower;
error[1] = bindThrower;
error[2] = new Object[] { decontValue.st.WHAT, nomType.st.WHAT, varName };
}
else
else {
error[0] = String.format(
"Nominal type check failed for parameter '%s'",
varName);
}
}

/* Report junction failure mode if it's a junction. */
Expand Down Expand Up @@ -714,7 +715,7 @@ else if ((flags & SIG_ELEM_HASH_SIGIL) != 0) {
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ }, null);
public static int bind(ThreadContext tc, RakOps.GlobalExt gcx, CallFrame cf, SixModelObject params,
CallSiteDescriptor csd, Object[] args,
boolean noNomTypeCheck, String[] error) {
boolean noNomTypeCheck, Object[] error) {
int bindFail = BIND_RESULT_OK;
int curPosArg = 0;

Expand Down
20 changes: 16 additions & 4 deletions src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java
Expand Up @@ -221,10 +221,16 @@ public static CallSiteDescriptor p6bindsig(ThreadContext tc, CallSiteDescriptor
.get_attribute_boxed(tc, gcx.Signature, "$!params", HINT_SIG_PARAMS);

/* Run binder, and handle any errors. */
String[] error = new String[1];
Object[] error = new Object[3];
switch (Binder.bind(tc, gcx, cf, params, csd, args, false, error)) {
case Binder.BIND_RESULT_FAIL:
throw ExceptionHandling.dieInternal(tc, error[0]);
if (error[0] instanceof String) {
throw ExceptionHandling.dieInternal(tc, (String) error[0]);
}
else {
Ops.invokeDirect(tc, (SixModelObject) error[0],
(CallSiteDescriptor) error[1], (Object[]) error[2]);
}
case Binder.BIND_RESULT_JUNCTION:
/* Invoke the auto-threader. */
csd = csd.injectInvokee(tc, args, cf.codeRef.codeObject);
Expand All @@ -250,11 +256,17 @@ public static SixModelObject p6bindcaptosig(SixModelObject sig, SixModelObject c
SixModelObject params = sig.get_attribute_boxed(tc, gcx.Signature,
"$!params", HINT_SIG_PARAMS);

String[] error = new String[1];
Object[] error = new Object[3];
switch (Binder.bind(tc, gcx, cf, params, csd, tc.flatArgs, false, error)) {
case Binder.BIND_RESULT_FAIL:
case Binder.BIND_RESULT_JUNCTION:
throw ExceptionHandling.dieInternal(tc, error[0]);
if (error[0] instanceof String) {
throw ExceptionHandling.dieInternal(tc, (String) error[0]);
}
else {
Ops.invokeDirect(tc, (SixModelObject) error[0],
(CallSiteDescriptor) error[1], (Object[]) error[2]);
}
default:
return sig;
}
Expand Down

0 comments on commit fe5b300

Please sign in to comment.