From 9d20b71ecaffbda5311dfc486b0143d4a94cc502 Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Wed, 25 Feb 2004 23:01:48 +0000 Subject: [PATCH] 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 --- include/llvm/ExecutionEngine/GenericValue.h | 1 + lib/ExecutionEngine/Interpreter/Execution.cpp | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h index 3fb66a11515..7cf1a7b3952 100644 --- a/include/llvm/ExecutionEngine/GenericValue.h +++ b/include/llvm/ExecutionEngine/GenericValue.h @@ -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]; diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 5379c04fbf6..953b0b4328a 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -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);