diff options
author | Chris Lattner <sabre@nondot.org> | 2001-07-25 22:47:55 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-07-25 22:47:55 +0000 |
commit | 90e0d464baa147c6255823cc41055f9f58dcabb9 (patch) | |
tree | 05274b778613cac7b57a397211e425264a7a21d3 /llvm/lib/Bytecode/Writer | |
parent | 42b5a8a6e5c4c8327d6a70c92ed80a459b60a684 (diff) | |
download | bcm5719-llvm-90e0d464baa147c6255823cc41055f9f58dcabb9.tar.gz bcm5719-llvm-90e0d464baa147c6255823cc41055f9f58dcabb9.zip |
Add support for extern varargs methods & varargs method calls
llvm-svn: 297
Diffstat (limited to 'llvm/lib/Bytecode/Writer')
-rw-r--r-- | llvm/lib/Bytecode/Writer/ConstantWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Bytecode/Writer/InstructionWriter.cpp | 53 |
2 files changed, 57 insertions, 4 deletions
diff --git a/llvm/lib/Bytecode/Writer/ConstantWriter.cpp b/llvm/lib/Bytecode/Writer/ConstantWriter.cpp index 7e2c9307b99..bac5a4c0502 100644 --- a/llvm/lib/Bytecode/Writer/ConstantWriter.cpp +++ b/llvm/lib/Bytecode/Writer/ConstantWriter.cpp @@ -28,6 +28,9 @@ void BytecodeWriter::outputType(const Type *T) { assert(Slot != -1 && "Type used but not available!!"); output_vbr((unsigned)Slot, Out); + // Output the number of arguments to method (+1 if varargs): + output_vbr(MT->getParamTypes().size()+MT->isVarArg(), Out); + // Output all of the arguments... MethodType::ParamTypes::const_iterator I = MT->getParamTypes().begin(); for (; I != MT->getParamTypes().end(); ++I) { @@ -36,8 +39,9 @@ void BytecodeWriter::outputType(const Type *T) { output_vbr((unsigned)Slot, Out); } - // Terminate list with VoidTy - output_vbr((unsigned)Type::VoidTy->getPrimitiveID(), Out); + // Terminate list with VoidTy if we are a varargs function... + if (MT->isVarArg()) + output_vbr((unsigned)Type::VoidTy->getPrimitiveID(), Out); break; } diff --git a/llvm/lib/Bytecode/Writer/InstructionWriter.cpp b/llvm/lib/Bytecode/Writer/InstructionWriter.cpp index a9b5e8d3041..18140772a39 100644 --- a/llvm/lib/Bytecode/Writer/InstructionWriter.cpp +++ b/llvm/lib/Bytecode/Writer/InstructionWriter.cpp @@ -35,8 +35,53 @@ static void outputInstructionFormat0(const Instruction *I, output_vbr(NumArgs, Out); for (unsigned i = 0; i < NumArgs; ++i) { - const Value *N = I->getOperand(i); - int Slot = Table.getValSlot(N); + int Slot = Table.getValSlot(I->getOperand(i)); + assert(Slot >= 0 && "No slot number for value!?!?"); + output_vbr((unsigned)Slot, Out); + } + align32(Out); // We must maintain correct alignment! +} + + +// outputInstrVarArgsCall - Output the obsurdly annoying varargs method calls. +// This are more annoying than most because the signature of the call does not +// tell us anything about the types of the arguments in the varargs portion. +// Because of this, we encode (as type 0) all of the argument types explicitly +// before the argument value. This really sucks, but you shouldn't be using +// varargs functions in your code! *death to printf*! +// +// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>] +// +static void outputInstrVarArgsCall(const Instruction *I, + const SlotCalculator &Table, unsigned Type, + vector<uchar> &Out) { + assert(I->getOpcode() == Instruction::Call /*|| + I->getOpcode() == Instruction::ICall */); + // Opcode must have top two bits clear... + output_vbr(I->getOpcode(), Out); // Instruction Opcode ID + output_vbr(Type, Out); // Result type (varargs type) + + unsigned NumArgs = I->getNumOperands(); + output_vbr((NumArgs-2)*2+2, Out); // Don't duplicate method & Arg1 types + + // Output the method type without an extra type argument. + int Slot = Table.getValSlot(I->getOperand(0)); + assert(Slot >= 0 && "No slot number for value!?!?"); + output_vbr((unsigned)Slot, Out); + + // VarArgs methods must have at least one specified operand + Slot = Table.getValSlot(I->getOperand(1)); + assert(Slot >= 0 && "No slot number for value!?!?"); + output_vbr((unsigned)Slot, Out); + + for (unsigned i = 2; i < NumArgs; ++i) { + // Output Arg Type ID + Slot = Table.getValSlot(I->getOperand(i)->getType()); + assert(Slot >= 0 && "No slot number for value!?!?"); + output_vbr((unsigned)Slot, Out); + + // Output arg ID itself + Slot = Table.getValSlot(I->getOperand(i)); assert(Slot >= 0 && "No slot number for value!?!?"); output_vbr((unsigned)Slot, Out); } @@ -161,6 +206,10 @@ bool BytecodeWriter::processInstruction(const Instruction *I) { assert(Slots[1] != -1 && "Cast return type unknown?"); if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; NumOperands++; + } else if (I->getOpcode() == Instruction::Call && // Handle VarArg calls + I->getOperand(0)->getType()->isMethodType()->isVarArg()) { + outputInstrVarArgsCall(I, Table, Type, Out); + return false; } // Decide which instruction encoding to use. This is determined primarily by |