Represent va_list in interpreter as a (ec-stack-depth . var-arg-index)

pair, and look up varargs in the execution stack every time, instead of
just pushing iterators (which can be invalidated during callFunction())
around.  (union GenericValue now has a "pair of uints" member, to support
this mechanism.) Fixes Bug 234.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11845 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Brian Gaeke 2004-02-25 23:01:48 +00:00
parent 367b91d1bd
commit 9d20b71eca
2 changed files with 15 additions and 11 deletions

View File

@ -33,6 +33,7 @@ union GenericValue {
int64_t LongVal;
double DoubleVal;
float FloatVal;
struct { unsigned int first; unsigned int second; } UIntPairVal;
PointerTy PointerVal;
unsigned char Untyped[8];

View File

@ -774,9 +774,13 @@ void Interpreter::visitCallSite(CallSite CS) {
switch (F->getIntrinsicID()) {
case Intrinsic::not_intrinsic:
break;
case Intrinsic::va_start: // va_start: implemented by getFirstVarArg()
SetValue(CS.getInstruction(), getFirstVarArg(), SF);
case Intrinsic::va_start: { // va_start
GenericValue ArgIndex;
ArgIndex.UIntPairVal.first = ECStack.size() - 1;
ArgIndex.UIntPairVal.second = 0;
SetValue(CS.getInstruction(), ArgIndex, SF);
return;
}
case Intrinsic::va_end: // va_end is a noop for the interpreter
return;
case Intrinsic::va_copy: // va_copy: dest = src
@ -960,14 +964,12 @@ void Interpreter::visitCastInst(CastInst &I) {
void Interpreter::visitVANextInst(VANextInst &I) {
ExecutionContext &SF = ECStack.back();
// Get the incoming valist parameter. LLI treats the valist as a pointer
// to the next argument.
// Get the incoming valist parameter. LLI treats the valist as a
// (ec-stack-depth var-arg-index) pair.
GenericValue VAList = getOperandValue(I.getOperand(0), SF);
// Move the pointer to the next vararg.
GenericValue *ArgPtr = (GenericValue *) GVTOP (VAList);
++ArgPtr;
VAList = PTOGV (ArgPtr);
++VAList.UIntPairVal.second;
SetValue(&I, VAList, SF);
}
@ -977,11 +979,12 @@ void Interpreter::visitVANextInst(VANextInst &I) {
void Interpreter::visitVAArgInst(VAArgInst &I) {
ExecutionContext &SF = ECStack.back();
// Get the incoming valist parameter. LLI treats the valist as a pointer
// to the next argument.
// Get the incoming valist parameter. LLI treats the valist as a
// (ec-stack-depth var-arg-index) pair.
GenericValue VAList = getOperandValue(I.getOperand(0), SF);
assert (GVTOP (VAList) != 0 && "VAList was null in vaarg instruction");
GenericValue Dest, Src = *(GenericValue *) GVTOP (VAList);
GenericValue Dest;
GenericValue Src = ECStack[VAList.UIntPairVal.first]
.VarArgs[VAList.UIntPairVal.second];
const Type *Ty = I.getType();
switch (Ty->getPrimitiveID()) {
IMPLEMENT_VAARG(UByte);