Skip to content

Commit 343fb95

Browse files
committed
Unbust Rakudo after indy arg handling work.
1 parent a7f2425 commit 343fb95

File tree

1 file changed

+71
-58
lines changed

1 file changed

+71
-58
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,10 +3218,61 @@ class QAST::CompilerJAST {
32183218
)
32193219
)
32203220
}
3221-
3221+
3222+
my $ARG_EXP_USE_BINDER := 0;
3223+
my $ARG_EXP_NO_ARGS := 1;
3224+
my $ARG_EXP_OBJ := 2;
3225+
method try_setup_args_expectation($jmeth, $block, $il) {
3226+
# Needing an args array forces the binder.
3227+
if $*NEED_ARGS_ARRAY {
3228+
return $ARG_EXP_USE_BINDER;
3229+
}
3230+
3231+
# Otherwise, go by arity, then look at particular cases.
3232+
my int $num_params := +$block.params;
3233+
if $num_params == 0 {
3234+
# Easy; just don't add any extra args in.
3235+
$jmeth.args_expectation($ARG_EXP_NO_ARGS);
3236+
return $ARG_EXP_NO_ARGS;
3237+
}
3238+
elsif $num_params == 1 {
3239+
# Look for one required positional case. Methods with no params
3240+
# beyond the invocant are always this.
3241+
my $param := $block.params[0];
3242+
if !$param.named && !$param.slurpy && !$param.default {
3243+
if nqp::objprimspec($param.returns) == 0 {
3244+
$jmeth.add_argument('__arg_0', $TYPE_SMO);
3245+
$il.append(JAST::Instruction.new( :op('aload'), '__arg_0' ));
3246+
if $param.scope eq 'local' {
3247+
$il.append(JAST::Instruction.new( :op('astore'), $param.name ));
3248+
}
3249+
else {
3250+
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
3251+
$il.append(JAST::PushIndex.new( :value($block.lexical_idx($param.name)) ));
3252+
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
3253+
'bindlex_o', $TYPE_SMO, $TYPE_SMO, $TYPE_CF, 'Integer' ));
3254+
$il.append($POP);
3255+
}
3256+
$jmeth.args_expectation($ARG_EXP_OBJ);
3257+
return $ARG_EXP_OBJ;
3258+
}
3259+
else {
3260+
return $ARG_EXP_USE_BINDER;
3261+
}
3262+
}
3263+
else {
3264+
return $ARG_EXP_USE_BINDER;
3265+
}
3266+
}
3267+
else {
3268+
return $ARG_EXP_USE_BINDER;
3269+
}
3270+
}
3271+
32223272
multi method as_jast(QAST::Block $node, :$want) {
32233273
# Do block compilation in a nested block, so we can produce a result based on
32243274
# the containing block's stack.
3275+
my int $args_expectation;
32253276
unless $*CODEREFS.know_cuid($node.cuid) {
32263277
# Block gets fresh BlockInfo.
32273278
my $*BINDVAL := 0;
@@ -3407,6 +3458,7 @@ class QAST::CompilerJAST {
34073458
$param_idx++;
34083459
}
34093460
}
3461+
$args_expectation := $*JMETH.args_expectation();
34103462

34113463
# Add all the locals.
34123464
my @all_locals;
@@ -3600,8 +3652,7 @@ class QAST::CompilerJAST {
36003652
elsif $blocktype eq 'immediate' || $blocktype eq 'immediate_static' {
36013653
# Can emit a direct JVM level call. First, get self, TC,
36023654
# code ref, and callsite descriptor (empty) onto the stack.
3603-
# We know immediate blocks have no args, so simply don't
3604-
# pass any.
3655+
# May or may not need args array.
36053656
my $il := JAST::InstructionList.new();
36063657
$*STACK.spill_to_locals($il);
36073658
$il.append($ALOAD_0);
@@ -3613,13 +3664,25 @@ class QAST::CompilerJAST {
36133664
$il.append(JAST::Instruction.new( :op('getstatic'),
36143665
$TYPE_OPS, 'emptyCallSite', $TYPE_CSD ));
36153666
$il.append($ACONST_NULL);
3667+
if $args_expectation != $ARG_EXP_NO_ARGS {
3668+
$il.append(JAST::Instruction.new( :op('getstatic'),
3669+
$TYPE_OPS, 'emptyArgList', "[$TYPE_OBJ" ));
3670+
}
36163671

36173672
# Emit the virtual call.
3618-
$il.append(savesite(JAST::Instruction.new( :op('invokestatic'),
3619-
'L' ~ $*JCLASS.name ~ ';',
3620-
$*CODEREFS.cuid_to_jastmethname($node.cuid),
3621-
'V', $TYPE_CU, $TYPE_TC, $TYPE_CR, $TYPE_CSD, $TYPE_RESUME )));
3622-
3673+
if $args_expectation == $ARG_EXP_NO_ARGS {
3674+
$il.append(savesite(JAST::Instruction.new( :op('invokestatic'),
3675+
'L' ~ $*JCLASS.name ~ ';',
3676+
$*CODEREFS.cuid_to_jastmethname($node.cuid),
3677+
'V', $TYPE_CU, $TYPE_TC, $TYPE_CR, $TYPE_CSD, $TYPE_RESUME )));
3678+
}
3679+
else {
3680+
$il.append(savesite(JAST::Instruction.new( :op('invokestatic'),
3681+
'L' ~ $*JCLASS.name ~ ';',
3682+
$*CODEREFS.cuid_to_jastmethname($node.cuid),
3683+
'V', $TYPE_CU, $TYPE_TC, $TYPE_CR, $TYPE_CSD, $TYPE_RESUME, "[$TYPE_OBJ" )));
3684+
}
3685+
36233686
# Load result onto the stack, unless in void context.
36243687
if $*WANT != $RT_VOID {
36253688
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
@@ -3640,56 +3703,6 @@ class QAST::CompilerJAST {
36403703
}
36413704
}
36423705

3643-
my $ARG_EXP_USE_BINDER := 0;
3644-
my $ARG_EXP_NO_ARGS := 1;
3645-
my $ARG_EXP_OBJ := 2;
3646-
method try_setup_args_expectation($jmeth, $block, $il) {
3647-
# Needing an args array forces the binder.
3648-
if $*NEED_ARGS_ARRAY {
3649-
return $ARG_EXP_USE_BINDER;
3650-
}
3651-
3652-
# Otherwise, go by arity, then look at particular cases.
3653-
my int $num_params := +$block.params;
3654-
if $num_params == 0 {
3655-
# Easy; just don't add any extra args in.
3656-
$jmeth.args_expectation($ARG_EXP_NO_ARGS);
3657-
return $ARG_EXP_NO_ARGS;
3658-
}
3659-
elsif $num_params == 1 {
3660-
# Look for one required positional case. Methods with no params
3661-
# beyond the invocant are always this.
3662-
my $param := $block.params[0];
3663-
if !$param.named && !$param.slurpy && !$param.default {
3664-
if nqp::objprimspec($param.returns) == 0 {
3665-
$jmeth.add_argument('__arg_0', $TYPE_SMO);
3666-
$il.append(JAST::Instruction.new( :op('aload'), '__arg_0' ));
3667-
if $param.scope eq 'local' {
3668-
$il.append(JAST::Instruction.new( :op('astore'), $param.name ));
3669-
}
3670-
else {
3671-
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
3672-
$il.append(JAST::PushIndex.new( :value($block.lexical_idx($param.name)) ));
3673-
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
3674-
'bindlex_o', $TYPE_SMO, $TYPE_SMO, $TYPE_CF, 'Integer' ));
3675-
$il.append($POP);
3676-
}
3677-
$jmeth.args_expectation($ARG_EXP_OBJ);
3678-
return $ARG_EXP_OBJ;
3679-
}
3680-
else {
3681-
return $ARG_EXP_USE_BINDER;
3682-
}
3683-
}
3684-
else {
3685-
return $ARG_EXP_USE_BINDER;
3686-
}
3687-
}
3688-
else {
3689-
return $ARG_EXP_USE_BINDER;
3690-
}
3691-
}
3692-
36933706
multi method as_jast(QAST::Stmts $node, :$want) {
36943707
self.compile_all_the_stmts($node.list, $node.resultchild, :node($node.node))
36953708
}

0 commit comments

Comments
 (0)