Skip to content

Commit 7e17160

Browse files
committed
Also special-case (obj,obj); also very common.
1 parent 343fb95 commit 7e17160

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,6 +3222,7 @@ class QAST::CompilerJAST {
32223222
my $ARG_EXP_USE_BINDER := 0;
32233223
my $ARG_EXP_NO_ARGS := 1;
32243224
my $ARG_EXP_OBJ := 2;
3225+
my $ARG_EXP_OBJ_OBJ := 3;
32253226
method try_setup_args_expectation($jmeth, $block, $il) {
32263227
# Needing an args array forces the binder.
32273228
if $*NEED_ARGS_ARRAY {
@@ -3264,6 +3265,38 @@ class QAST::CompilerJAST {
32643265
return $ARG_EXP_USE_BINDER;
32653266
}
32663267
}
3268+
elsif $num_params == 2 {
3269+
my $is_obj_obj := 1;
3270+
for $block.params {
3271+
if $_.named || $_.slurpy || $_.default || nqp::objprimspec($_.returns) != 0 {
3272+
$is_obj_obj := 0;
3273+
last;
3274+
}
3275+
}
3276+
if $is_obj_obj {
3277+
my int $i := 0;
3278+
for $block.params {
3279+
$jmeth.add_argument("__arg_$i", $TYPE_SMO);
3280+
$il.append(JAST::Instruction.new( :op('aload'), "__arg_$i" ));
3281+
if $_.scope eq 'local' {
3282+
$il.append(JAST::Instruction.new( :op('astore'), $_.name ));
3283+
}
3284+
else {
3285+
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
3286+
$il.append(JAST::PushIndex.new( :value($block.lexical_idx($_.name)) ));
3287+
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
3288+
'bindlex_o', $TYPE_SMO, $TYPE_SMO, $TYPE_CF, 'Integer' ));
3289+
$il.append($POP);
3290+
}
3291+
$i++;
3292+
}
3293+
$jmeth.args_expectation($ARG_EXP_OBJ_OBJ);
3294+
return $ARG_EXP_OBJ_OBJ;
3295+
}
3296+
else {
3297+
return $ARG_EXP_USE_BINDER;
3298+
}
3299+
}
32673300
else {
32683301
return $ARG_EXP_USE_BINDER;
32693302
}

src/vm/jvm/runtime/org/perl6/nqp/runtime/ArgsExpectation.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class ArgsExpectation {
1212
public static final short USE_BINDER = 0;
1313
public static final short NO_ARGS = 1;
1414
public static final short OBJ = 2;
15+
public static final short OBJ_OBJ = 3;
1516

1617
public static void invokeByExpectation(ThreadContext tc, CodeRef cr,
1718
CallSiteDescriptor csd, Object[] args) throws Throwable {
@@ -72,6 +73,67 @@ public static void invokeByExpectation(ThreadContext tc, CodeRef cr,
7273
}
7374
}
7475
break;
76+
case ArgsExpectation.OBJ_OBJ:
77+
if (csd.argFlags.length == 2 && csd.argFlags[0] == CallSiteDescriptor.ARG_OBJ
78+
&& csd.argFlags[1] == CallSiteDescriptor.ARG_OBJ) {
79+
/* Simple, common case. */
80+
cr.staticInfo.mh.invokeExact(tc, cr, csd,
81+
(SixModelObject)args[0], (SixModelObject)args[1]);
82+
}
83+
else {
84+
/* Flatten if needed. */
85+
if (csd.hasFlattening) {
86+
csd = csd.explodeFlattening(tc.curFrame, args);
87+
args = tc.flatArgs;
88+
}
89+
if (csd.argFlags.length == 2) {
90+
SixModelObject arg1 = null;
91+
SixModelObject arg2 = null;
92+
switch (csd.argFlags[0]) {
93+
case CallSiteDescriptor.ARG_OBJ:
94+
arg1 = (SixModelObject)args[0];
95+
break;
96+
case CallSiteDescriptor.ARG_INT:
97+
arg1 = Ops.box_i((long)args[0], cr.staticInfo.compUnit.hllConfig.intBoxType, tc);
98+
break;
99+
case CallSiteDescriptor.ARG_NUM:
100+
arg1 = Ops.box_n((double)args[0], cr.staticInfo.compUnit.hllConfig.numBoxType, tc);
101+
break;
102+
case CallSiteDescriptor.ARG_STR:
103+
arg1 = Ops.box_s((String)args[0], cr.staticInfo.compUnit.hllConfig.strBoxType, tc);
104+
break;
105+
default:
106+
ExceptionHandling.dieInternal(tc,
107+
"Wrong number of arguments passed; expected 2..2, but got " +
108+
csd.numPositionals);
109+
}
110+
switch (csd.argFlags[1]) {
111+
case CallSiteDescriptor.ARG_OBJ:
112+
arg2 = (SixModelObject)args[1];
113+
break;
114+
case CallSiteDescriptor.ARG_INT:
115+
arg2 = Ops.box_i((long)args[1], cr.staticInfo.compUnit.hllConfig.intBoxType, tc);
116+
break;
117+
case CallSiteDescriptor.ARG_NUM:
118+
arg2 = Ops.box_n((double)args[1], cr.staticInfo.compUnit.hllConfig.numBoxType, tc);
119+
break;
120+
case CallSiteDescriptor.ARG_STR:
121+
arg2 = Ops.box_s((String)args[1], cr.staticInfo.compUnit.hllConfig.strBoxType, tc);
122+
break;
123+
default:
124+
ExceptionHandling.dieInternal(tc,
125+
"Wrong number of arguments passed; expected 2..2, but got " +
126+
csd.numPositionals);
127+
}
128+
cr.staticInfo.mh.invokeExact(tc, cr, csd, arg1, arg2);
129+
}
130+
else {
131+
ExceptionHandling.dieInternal(tc,
132+
"Wrong number of arguments passed; expected 2..2, but got " +
133+
csd.numPositionals);
134+
}
135+
}
136+
break;
75137
default:
76138
ExceptionHandling.dieInternal(tc, "Unknown Argument Expectation in invoke");
77139
}

src/vm/jvm/runtime/org/perl6/nqp/runtime/StaticCodeInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ else if (t.parameterCount() >= 4 && (t.parameterType(3) == ResumeStatus.Frame.cl
187187
case ArgsExpectation.OBJ:
188188
mhResume = MethodHandles.insertArguments(mhResume, 1, (SixModelObject)null);
189189
break;
190+
case ArgsExpectation.OBJ_OBJ:
191+
mhResume = MethodHandles.insertArguments(mhResume, 1,
192+
(SixModelObject)null, (SixModelObject)null);
193+
break;
190194
default:
191195
throw new RuntimeException("Unhandled ArgsExpectation in StaticCodeInfo");
192196
}

0 commit comments

Comments
 (0)