From 54edbee001630b8d0c28e432fe1045da46693086 Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Sun, 29 Jun 2014 14:00:54 -0500 Subject: [PATCH] [pmc2c] add method arity check - GH #1080 on method calls without optional args do one arity check, with the new exception message: "wrong number of arguments: %d passed, %d expected" Matching the old exception message too many/few would require two run-time checks, which costs ~2% in parrot-bench. fixes t/pmc/class.t --- lib/Parrot/Pmc2c/PCCMETHOD.pm | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/Parrot/Pmc2c/PCCMETHOD.pm b/lib/Parrot/Pmc2c/PCCMETHOD.pm index 738a0c217d..178189defd 100644 --- a/lib/Parrot/Pmc2c/PCCMETHOD.pm +++ b/lib/Parrot/Pmc2c/PCCMETHOD.pm @@ -402,10 +402,19 @@ END END # SKIP fast code for c,f,l,n,o,p,s arg adverbs if ($params_signature and $params_signature !~ /[cflnops]/) { # new fast branch - my $arg_index = 0; my @sig_vals = split(//,$params_signature); my @params_vararg_list = split(/, &/,(substr $params_varargs, 1)); - + my ($arg_index, $arity) = (0, 0); + $params_signature =~ s/([PSIN])/$arity++; $1/ge; + $e->emit( <<"END"); + const INTVAL arity = $arity; /* \"$params_signature\" */ + INTVAL param_count = VTABLE_elements(interp, _call_object); + if (param_count != arity) + Parrot_ex_throw_from_c_args(interp, NULL, + EXCEPTION_INVALID_OPERATION, + "wrong number of arguments: %d passed, %d expected", + param_count, arity); +END # TODO: handle o for optional, and c for constant foreach my $sig (@sig_vals) { my $type = convert_pcc_sigtype($sig); @@ -415,9 +424,10 @@ END END $arg_index++; } - elsif ($sig eq 'i' # for invocant - and $params_vararg_list[$arg_index - 1] eq '_self' - and $sig_vals[$arg_index - 1] eq 'P') { + elsif ($sig eq 'i' # ignore i for Pi :invocant, already done above + and $arg_index == 1 + and $params_vararg_list[0] eq '_self' + and $sig_vals[0] eq 'P') { } else { warn "Warning: ".$pmc->name.".".$method->name."(\"$params_signature\"): unhandled arg adverb $sig for $params_vararg_list[$arg_index - 1]";