mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
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:
parent
367b91d1bd
commit
9d20b71eca
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user