Change LLI's internal representation of va_list to a pointer to the next
authorBrian Gaeke <gaeke@uiuc.edu>
Thu, 13 Nov 2003 06:06:01 +0000 (06:06 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Thu, 13 Nov 2003 06:06:01 +0000 (06:06 +0000)
argument to be returned by va_arg. This allows va_lists to be passed
between different LLVM procedures (though it is unlikely that an LLI
va_list would make sense to an external function, except by chance.)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9965 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/Interpreter/Execution.cpp
lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
lib/ExecutionEngine/Interpreter/Interpreter.h

index aa32983cc38dce8565c2fb502ed184bed820076c..d668ee710af14defa7ec062ac3a0b239e623671b 100644 (file)
@@ -812,13 +812,14 @@ void Interpreter::visitCastInst(CastInst &I) {
 void Interpreter::visitVANextInst(VANextInst &I) {
   ExecutionContext &SF = ECStack.back();
 
-  // Get the incoming valist element.  LLI treats the valist as an integer.
+  // Get the incoming valist parameter.  LLI treats the valist as a pointer 
+  // to the next argument.
   GenericValue VAList = getOperandValue(I.getOperand(0), SF);
   
-  // Move to the next operand.
-  unsigned Argument = VAList.IntVal++;
-  assert(Argument < SF.VarArgs.size() &&
-         "Accessing past the last vararg argument!");
+  // Move the pointer to the next vararg.
+  GenericValue *ArgPtr = (GenericValue *) GVTOP (VAList);
+  ++ArgPtr;
+  VAList = PTOGV (ArgPtr);
   SetValue(&I, VAList, SF);
 }
 
@@ -828,12 +829,11 @@ void Interpreter::visitVANextInst(VANextInst &I) {
 void Interpreter::visitVAArgInst(VAArgInst &I) {
   ExecutionContext &SF = ECStack.back();
 
-  // Get the incoming valist element.  LLI treats the valist as an integer.
+  // Get the incoming valist parameter.  LLI treats the valist as a pointer 
+  // to the next argument.
   GenericValue VAList = getOperandValue(I.getOperand(0), SF);
-  unsigned Argument = VAList.IntVal;
-  assert(Argument < SF.VarArgs.size() &&
-         "Accessing past the last vararg argument!");
-  GenericValue Dest, Src = SF.VarArgs[Argument];
+  assert (GVTOP (VAList) != 0 && "VAList was null in vaarg instruction");
+  GenericValue Dest, Src = *(GenericValue *) GVTOP (VAList);
   const Type *Ty = I.getType();
   switch (Ty->getPrimitiveID()) {
     IMPLEMENT_VAARG(UByte);
index f516f5de23e3e43a27e60b0aec561389ee7c8a32..b547e5231f8183e9e3943333d5d027efd245f6cd 100644 (file)
@@ -696,9 +696,7 @@ GenericValue lle_X_fprintf(FunctionType *M, const vector<GenericValue> &Args) {
 // <va_list> llvm.va_start() - Implement the va_start operation...
 GenericValue llvm_va_start(FunctionType *F, const vector<GenericValue> &Args) {
   assert(Args.size() == 0);
-  GenericValue Val;
-  Val.UIntVal = 0;   // Start at the first '...' argument...
-  return Val;
+  return TheInterpreter->getFirstVarArg();
 }
 
 // void llvm.va_end(<va_list> *) - Implement the va_end operation...
index e9015a203e9f36fbafaf0f6db1a741fc97b4f8ff..380672ac72e4fe4f5159f475af161b3d611bacb6 100644 (file)
@@ -146,6 +146,10 @@ public:
     AtExitHandlers.push_back(F);
   }
 
+  GenericValue *getFirstVarArg () {
+    return &(ECStack[ECStack.size () - 2].VarArgs[0]);
+  }
+
   //FIXME: private:
 public:
   GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I,