Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Eliminate callsite field in CallFrame.
  • Loading branch information
jnthn committed Mar 2, 2013
1 parent 0408144 commit 2159682
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 98 deletions.
32 changes: 25 additions & 7 deletions lib/QAST/JASTCompiler.nqp
Expand Up @@ -1476,8 +1476,22 @@ QAST::OperationsJAST.map_classlib_core_op('lexprimspec', $TYPE_OPS, 'lexprimspec

# Argument capture processing, for writing things like multi-dispatchers in
# high level languages.
QAST::OperationsJAST.map_classlib_core_op('usecapture', $TYPE_OPS, 'usecapture', [], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('savecapture', $TYPE_OPS, 'savecapture', [], $RT_OBJ, :tc);
QAST::OperationsJAST.add_core_op('usecapture', -> $qastcomp, $op {
my $il := JAST::InstructionList.new();
$il.append(JAST::Instruction.new( :op('aload_1') ));
$il.append(JAST::Instruction.new( :op('aload'), 'csd' ));
$il.append(JAST::Instruction.new( :op('invokestatic'),
$TYPE_OPS, 'usecapture', $TYPE_SMO, $TYPE_TC, $TYPE_CSD ));
result($il, $RT_OBJ)
});
QAST::OperationsJAST.add_core_op('savecapture', -> $qastcomp, $op {
my $il := JAST::InstructionList.new();
$il.append(JAST::Instruction.new( :op('aload_1') ));
$il.append(JAST::Instruction.new( :op('aload'), 'csd' ));
$il.append(JAST::Instruction.new( :op('invokestatic'),
$TYPE_OPS, 'savecapture', $TYPE_SMO, $TYPE_TC, $TYPE_CSD ));
result($il, $RT_OBJ)
});
QAST::OperationsJAST.map_classlib_core_op('captureposelems', $TYPE_OPS, 'captureposelems', [$RT_OBJ], $RT_INT, :tc);
QAST::OperationsJAST.map_classlib_core_op('captureposarg', $TYPE_OPS, 'captureposarg', [$RT_OBJ, $RT_INT], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('captureposarg_i', $TYPE_OPS, 'captureposarg_i', [$RT_OBJ, $RT_INT], $RT_INT, :tc);
Expand Down Expand Up @@ -2691,10 +2705,12 @@ class QAST::CompilerJAST {
# Emit arity check instruction.
my $il := JAST::InstructionList.new();
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
$il.append(JAST::Instruction.new( :op('aload'), 'csd' ));
$il.append(JAST::PushIndex.new( :value($pos_required) ));
$il.append(JAST::PushIndex.new( :value($pos_slurpy ?? -1 !! $pos_required + $pos_optional) ));
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
"checkarity", 'Void', $TYPE_CF, 'Integer', 'Integer' ));
"checkarity", $TYPE_CSD, $TYPE_CF, $TYPE_CSD, 'Integer', 'Integer' ));
$il.append(JAST::Instruction.new( :op('astore'), 'csd' ));

# Emit instructions to load each parameter.
my int $param_idx := 0;
Expand All @@ -2704,14 +2720,15 @@ class QAST::CompilerJAST {
$type := $RT_OBJ;
$il.append(JAST::Instruction.new( :op('aload_1') ));
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
$il.append(JAST::Instruction.new( :op('aload'), 'csd' ));
if $_.named {
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
"namedslurpy", $TYPE_SMO, $TYPE_TC, $TYPE_CF ));
"namedslurpy", $TYPE_SMO, $TYPE_TC, $TYPE_CF, $TYPE_CSD ));
}
else {
$il.append(JAST::PushIndex.new( :value($pos_required + $pos_optional) ));
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
"posslurpy", $TYPE_SMO, $TYPE_TC, $TYPE_CF, 'Integer' ));
"posslurpy", $TYPE_SMO, $TYPE_TC, $TYPE_CF, $TYPE_CSD, 'Integer' ));
}
}
else {
Expand All @@ -2720,15 +2737,16 @@ class QAST::CompilerJAST {
my $tc := typechar($type);
my $opt := $_.default ?? "opt_" !! "";
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
$il.append(JAST::Instruction.new( :op('aload'), 'csd' ));
if $_.named {
$il.append(JAST::PushSVal.new( :value($_.named) ));
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
"namedparam_$opt$tc", $jt, $TYPE_CF, $TYPE_STR ));
"namedparam_$opt$tc", $jt, $TYPE_CF, $TYPE_CSD, $TYPE_STR ));
}
else {
$il.append(JAST::PushIndex.new( :value($param_idx) ));
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
"posparam_$opt$tc", $jt, $TYPE_CF, 'Integer' ));
"posparam_$opt$tc", $jt, $TYPE_CF, $TYPE_CSD, 'Integer' ));
}
if $opt {
my $lbl := JAST::Label.new( :name(self.unique("opt_param")) );
Expand Down
5 changes: 0 additions & 5 deletions src/org/perl6/nqp/runtime/CallFrame.java
Expand Up @@ -15,11 +15,6 @@ public class CallFrame {
*/
public ThreadContext tc;

/**
* Call site descriptor, describing the kinds of arguments being passed.
*/
public CallSiteDescriptor callSite;

/**
* The next entry in the static (lexical) chain.
*/
Expand Down
6 changes: 4 additions & 2 deletions src/org/perl6/nqp/runtime/CallSiteDescriptor.java
Expand Up @@ -96,7 +96,7 @@ public CallSiteDescriptor(byte[] flags, String[] names) {
/* Explodes any flattening parts. Creates and puts in place a new callsite
* and enlarged-as-needed argument arrays.
*/
public void explodeFlattening(CallFrame cf) {
public CallSiteDescriptor explodeFlattening(CallFrame cf) {
ArrayList<Byte> newFlags = new ArrayList<Byte>();
ArrayList<SixModelObject> newObjArgs = new ArrayList<SixModelObject>();
ArrayList<String> newNames = new ArrayList<String>();
Expand Down Expand Up @@ -155,11 +155,13 @@ public void explodeFlattening(CallFrame cf) {
String[] newNamesArr = new String[newNames.size()];
for (int i = 0; i < newNamesArr.length; i++)
newNamesArr[i] = newNames.get(i);
cf.callSite = new CallSiteDescriptor(newFlagsArr, newNamesArr);
CallSiteDescriptor exploded = new CallSiteDescriptor(newFlagsArr, newNamesArr);

if (cf.proc_oArg.length < newObjArgs.size())
cf.proc_oArg = new SixModelObject[newObjArgs.size()];
for (int i = 0; i < newObjArgs.size(); i++)
cf.proc_oArg[i] = newObjArgs.get(i);

return exploded;
}
}
83 changes: 32 additions & 51 deletions src/org/perl6/nqp/runtime/Ops.java
Expand Up @@ -709,20 +709,20 @@ public static long lexprimspec(SixModelObject pad, String key, ThreadContext tc)
public static void arg(SixModelObject v, SixModelObject[] args, int i) { args[i] = v; }

/* Invocation arity check. */
public static void checkarity(CallFrame cf, int required, int accepted) {
public static CallSiteDescriptor checkarity(CallFrame cf, CallSiteDescriptor cs, int required, int accepted) {
if (cf.caller != null)
cf.proc_oArg = cf.caller.oArg;
if (cf.callSite.hasFlattening)
cf.callSite.explodeFlattening(cf);
int positionals = cf.callSite.numPositionals;
if (cs.hasFlattening)
cs = cs.explodeFlattening(cf);
int positionals = cs.numPositionals;
if (positionals < required || positionals > accepted && accepted != -1)
throw ExceptionHandling.dieInternal(cf.tc, "Wrong number of arguments passed; expected " +
required + ".." + accepted + ", but got " + positionals);
return cs;
}

/* Required positional parameter fetching. */
public static SixModelObject posparam_o(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static SixModelObject posparam_o(CallFrame cf, CallSiteDescriptor cs, int idx) {
switch (cs.argFlags[idx]) {
case CallSiteDescriptor.ARG_OBJ:
return cf.proc_oArg[cs.argIdx[idx]];
Expand All @@ -736,8 +736,7 @@ public static SixModelObject posparam_o(CallFrame cf, int idx) {
throw ExceptionHandling.dieInternal(cf.tc, "Error in argument processing");
}
}
public static long posparam_i(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static long posparam_i(CallFrame cf, CallSiteDescriptor cs, int idx) {
switch (cs.argFlags[idx]) {
case CallSiteDescriptor.ARG_INT:
return cf.caller.iArg[cs.argIdx[idx]];
Expand All @@ -751,8 +750,7 @@ public static long posparam_i(CallFrame cf, int idx) {
throw ExceptionHandling.dieInternal(cf.tc, "Error in argument processing");
}
}
public static double posparam_n(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static double posparam_n(CallFrame cf, CallSiteDescriptor cs, int idx) {
switch (cs.argFlags[idx]) {
case CallSiteDescriptor.ARG_NUM:
return cf.caller.nArg[cs.argIdx[idx]];
Expand All @@ -766,8 +764,7 @@ public static double posparam_n(CallFrame cf, int idx) {
throw ExceptionHandling.dieInternal(cf.tc, "Error in argument processing");
}
}
public static String posparam_s(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static String posparam_s(CallFrame cf, CallSiteDescriptor cs, int idx) {
switch (cs.argFlags[idx]) {
case CallSiteDescriptor.ARG_STR:
return cf.caller.sArg[cs.argIdx[idx]];
Expand All @@ -783,44 +780,40 @@ public static String posparam_s(CallFrame cf, int idx) {
}

/* Optional positional parameter fetching. */
public static SixModelObject posparam_opt_o(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static SixModelObject posparam_opt_o(CallFrame cf, CallSiteDescriptor cs, int idx) {
if (idx < cs.numPositionals) {
cf.tc.lastParameterExisted = 1;
return posparam_o(cf, idx);
return posparam_o(cf, cs, idx);
}
else {
cf.tc.lastParameterExisted = 0;
return null;
}
}
public static long posparam_opt_i(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static long posparam_opt_i(CallFrame cf, CallSiteDescriptor cs, int idx) {
if (idx < cs.numPositionals) {
cf.tc.lastParameterExisted = 1;
return posparam_i(cf, idx);
return posparam_i(cf, cs, idx);
}
else {
cf.tc.lastParameterExisted = 0;
return 0;
}
}
public static double posparam_opt_n(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static double posparam_opt_n(CallFrame cf, CallSiteDescriptor cs, int idx) {
if (idx < cs.numPositionals) {
cf.tc.lastParameterExisted = 1;
return posparam_n(cf, idx);
return posparam_n(cf, cs, idx);
}
else {
cf.tc.lastParameterExisted = 0;
return 0.0;
}
}
public static String posparam_opt_s(CallFrame cf, int idx) {
CallSiteDescriptor cs = cf.callSite;
public static String posparam_opt_s(CallFrame cf, CallSiteDescriptor cs, int idx) {
if (idx < cs.numPositionals) {
cf.tc.lastParameterExisted = 1;
return posparam_s(cf, idx);
return posparam_s(cf, cs, idx);
}
else {
cf.tc.lastParameterExisted = 0;
Expand All @@ -829,9 +822,7 @@ public static String posparam_opt_s(CallFrame cf, int idx) {
}

/* Slurpy positional parameter. */
public static SixModelObject posslurpy(ThreadContext tc, CallFrame cf, int fromIdx) {
CallSiteDescriptor cs = cf.callSite;

public static SixModelObject posslurpy(ThreadContext tc, CallFrame cf, CallSiteDescriptor cs, int fromIdx) {
/* Create result. */
HLLConfig hllConfig = cf.codeRef.staticInfo.compUnit.hllConfig;
SixModelObject resType = hllConfig.slurpyArrayType;
Expand Down Expand Up @@ -860,8 +851,7 @@ public static SixModelObject posslurpy(ThreadContext tc, CallFrame cf, int fromI
}

/* Required named parameter getting. */
public static SixModelObject namedparam_o(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static SixModelObject namedparam_o(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -882,8 +872,7 @@ public static SixModelObject namedparam_o(CallFrame cf, String name) {
else
throw ExceptionHandling.dieInternal(cf.tc, "Required named argument '" + name + "' not passed");
}
public static long namedparam_i(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static long namedparam_i(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -904,8 +893,7 @@ public static long namedparam_i(CallFrame cf, String name) {
else
throw ExceptionHandling.dieInternal(cf.tc, "Required named argument '" + name + "' not passed");
}
public static double namedparam_n(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static double namedparam_n(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -926,8 +914,7 @@ public static double namedparam_n(CallFrame cf, String name) {
else
throw ExceptionHandling.dieInternal(cf.tc, "Required named argument '" + name + "' not passed");
}
public static String namedparam_s(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static String namedparam_s(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -950,8 +937,7 @@ public static String namedparam_s(CallFrame cf, String name) {
}

/* Optional named parameter getting. */
public static SixModelObject namedparam_opt_o(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static SixModelObject namedparam_opt_o(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -975,8 +961,7 @@ public static SixModelObject namedparam_opt_o(CallFrame cf, String name) {
return null;
}
}
public static long namedparam_opt_i(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static long namedparam_opt_i(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -1000,8 +985,7 @@ public static long namedparam_opt_i(CallFrame cf, String name) {
return 0;
}
}
public static double namedparam_opt_n(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static double namedparam_opt_n(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -1025,8 +1009,7 @@ public static double namedparam_opt_n(CallFrame cf, String name) {
return 0.0;
}
}
public static String namedparam_opt_s(CallFrame cf, String name) {
CallSiteDescriptor cs = cf.callSite;
public static String namedparam_opt_s(CallFrame cf, CallSiteDescriptor cs, String name) {
if (cf.workingNameMap == null)
cf.workingNameMap = new HashMap<String, Integer>(cs.nameMap);
Integer lookup = cf.workingNameMap.remove(name);
Expand All @@ -1052,8 +1035,7 @@ public static String namedparam_opt_s(CallFrame cf, String name) {
}

/* Slurpy named parameter. */
public static SixModelObject namedslurpy(ThreadContext tc, CallFrame cf) {
CallSiteDescriptor cs = cf.callSite;
public static SixModelObject namedslurpy(ThreadContext tc, CallFrame cf, CallSiteDescriptor cs) {

/* Create result. */
HLLConfig hllConfig = cf.codeRef.staticInfo.compUnit.hllConfig;
Expand Down Expand Up @@ -1145,21 +1127,21 @@ public static String result_s(CallFrame cf) {
}

/* Capture related operations. */
public static SixModelObject usecapture(ThreadContext tc) {
public static SixModelObject usecapture(ThreadContext tc, CallSiteDescriptor cs) {
CallCaptureInstance cc = tc.savedCC;
CallFrame cf = tc.curFrame;
cc.descriptor = tc.curFrame.callSite;
cc.descriptor = cs;
cc.oArg = cf.proc_oArg == null ? null : cf.proc_oArg.clone();
cc.iArg = cf.caller.iArg == null ? null : cf.caller.iArg.clone();
cc.nArg = cf.caller.nArg == null ? null : cf.caller.nArg.clone();
cc.sArg = cf.caller.sArg == null ? null : cf.caller.sArg.clone();
return cc;
}
public static SixModelObject savecapture(ThreadContext tc) {
public static SixModelObject savecapture(ThreadContext tc, CallSiteDescriptor cs) {
SixModelObject CallCapture = tc.gc.CallCapture;
CallCaptureInstance cc = (CallCaptureInstance)CallCapture.st.REPR.allocate(tc, CallCapture.st);
CallFrame cf = tc.curFrame;
cc.descriptor = tc.curFrame.callSite;
cc.descriptor = cs;
if (cf.caller.oArg != null)
cc.oArg = cf.caller.oArg.clone();
if (cf.caller.iArg != null)
Expand Down Expand Up @@ -1278,9 +1260,8 @@ private static void invokeInternal(ThreadContext tc, SixModelObject invokee, Cal
cr = (CodeRef)is.InvocationHandler;
}

// Create a new call frame and set caller and callsite.
// Create a new call frame.
CallFrame cf = new CallFrame(tc, cr);
cf.callSite = csd;

try {
// Do the invocation.
Expand Down

0 comments on commit 2159682

Please sign in to comment.