bug fixes for indirect function calls when using ZAM

This commit is contained in:
Vern Paxson 2023-12-04 16:50:27 -08:00
parent a927d61e59
commit 3d69b0551a
2 changed files with 39 additions and 18 deletions

View file

@ -953,8 +953,12 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
op = OP_WHENCALLN_V;
}
else if ( indirect )
op = n ? OP_INDCALLN_VV : OP_INDCALLN_V;
else if ( indirect ) {
if ( func_id->IsGlobal() )
op = n ? OP_INDCALLN_V : OP_INDCALLN_X;
else
op = n ? OP_LOCAL_INDCALLN_VV : OP_LOCAL_INDCALLN_V;
}
else
op = n ? OP_CALLN_V : OP_CALLN_X;
@ -968,11 +972,14 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
auto n_slot = Frame1Slot(n, OP1_WRITE);
if ( indirect ) {
if ( func_id->IsGlobal() )
z = ZInstI(op, n_slot, -1);
else
if ( func_id->IsGlobal() ) {
z = ZInstI(op, n_slot);
z.op_type = OP_V;
}
else {
z = ZInstI(op, n_slot, FrameSlot(func));
z.op_type = OP_VV;
z.op_type = OP_VV;
}
}
else {
@ -981,11 +988,8 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
}
}
else {
if ( indirect ) {
if ( func_id->IsGlobal() )
z = ZInstI(op, -1);
else
z = ZInstI(op, FrameSlot(func));
if ( indirect && ! func_id->IsGlobal() ) {
z = ZInstI(op, FrameSlot(func));
z.op_type = OP_V;
}
else {

View file

@ -183,8 +183,11 @@
# version for assigning to a frame variable
#
# indirect-call the operation represents an indirect call (through
# a variable, rather than directly). Only meaningful
# if num-call-args is also specified.
# a global variable, rather than directly). Only
# meaningful if num-call-args is also specified.
#
# indirect-local-call same, but via a local variable rather than
# global
#
# method-post C++ code to add to the end of the method that
# dynamically generates ZAM code
@ -1587,22 +1590,36 @@ side-effects OP_CALLN_X OP_X
assign-val v
num-call-args n
# Same, but for indirect calls via a local variable.
# Same, but for indirect calls via a global variable.
internal-op IndCallN
op1-read
type V
type X
side-effects
indirect-call
num-call-args n
# Same with a return value.
internal-assignment-op IndCallN
type VV
side-effects OP_INDCALLN_V OP_V
type V
side-effects OP_INDCALLN_X OP_X
assign-val v
indirect-call
num-call-args n
# And versions with a local variable rather than a global.
internal-op Local-IndCallN
op1-read
type V
side-effects
indirect-local-call
num-call-args n
internal-assignment-op Local-IndCallN
type VV
side-effects OP_LOCAL_INDCALLN_V OP_V
assign-val v
indirect-local-call
num-call-args n
# A call made in a "when" context. These always have assignment targets.
# To keep things simple, we just use one generic flavor (for N arguments,
# doing a less-streamlined-but-simpler Val-based assignment).