diff options
| author | Chris Lattner <sabre@nondot.org> | 2001-10-13 06:47:01 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2001-10-13 06:47:01 +0000 | 
| commit | 05950c34a4297f26ec602ef5fe491b66addd745f (patch) | |
| tree | da0ab6ace9d38462d4230440c2e85e3bfa437f9e /lib/Bytecode/Reader/InstructionReader.cpp | |
| parent | e02fa8551d20081534afa46e0976811687e5183a (diff) | |
* Add real support for global variable addresses initializing constants
* Add minor optimization to BytecodeParser::refineAbstractType
* MethodType::get now take an explicit isVarArg parameter
* Fix encoding/decoding of VarArgs calls
* Support the Invoke instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@760 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode/Reader/InstructionReader.cpp')
| -rw-r--r-- | lib/Bytecode/Reader/InstructionReader.cpp | 83 | 
1 files changed, 71 insertions, 12 deletions
diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 5697b2620f..58f2656559 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -1,4 +1,4 @@ -//===- ReadInst.cpp - Code to read an instruction from bytecode -------------=== +//===- ReadInst.cpp - Code to read an instruction from bytecode -----------===//  //  // This file defines the mechanism to read an instruction from a bytecode   // stream. @@ -9,7 +9,7 @@  // TODO: Change from getValue(Raw.Arg1) etc, to getArg(Raw, 1)  //       Make it check type, so that casts are checked.  // -//===------------------------------------------------------------------------=== +//===----------------------------------------------------------------------===//  #include "llvm/iOther.h"  #include "llvm/iTerminators.h" @@ -193,13 +193,19 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,    }    case Instruction::Call: { -    Method *M = cast<Method>(getValue(Raw.Ty, Raw.Arg1)); +    Value *M = getValue(Raw.Ty, Raw.Arg1);      if (M == 0) return failure(true); +    // Check to make sure we have a pointer to method type +    PointerType *PTy = dyn_cast<PointerType>(M->getType()); +    if (PTy == 0) return failure(true); +    MethodType *MTy = dyn_cast<MethodType>(PTy->getValueType()); +    if (MTy == 0) return failure(true); +      vector<Value *> Params; -    const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes(); +    const MethodType::ParamTypes &PL = MTy->getParamTypes(); -    if (!M->getMethodType()->isVarArg()) { +    if (!MTy->isVarArg()) {        MethodType::ParamTypes::const_iterator It = PL.begin();        switch (Raw.NumOperands) { @@ -224,21 +230,74 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,        }        if (It != PL.end()) return failure(true);      } else { -      // The first parameter does not have a type specifier... because there -      // must be at least one concrete argument to a vararg type... -      Params.push_back(getValue(PL.front(), Raw.Arg2)); +      if (Raw.NumOperands > 2) { +	vector<unsigned> &args = *Raw.VarArgs; +	if (args.size() < 1) return failure(true); + +	if ((args.size() & 1) != 0) +	  return failure(true);  // Must be pairs of type/value +	for (unsigned i = 0; i < args.size(); i+=2) { +	  const Type *Ty = getType(args[i]); +	  if (Ty == 0) +	    return failure(true); +	   +	  Value *V = getValue(Ty, args[i+1]); +	  if (V == 0) return failure(true); +	  Params.push_back(V); +	} +	delete Raw.VarArgs; +      } +    } + +    Res = new CallInst(M, Params); +    return false; +  } +  case Instruction::Invoke: { +    Value *M = getValue(Raw.Ty, Raw.Arg1); +    if (M == 0) return failure(true); + +    // Check to make sure we have a pointer to method type +    PointerType *PTy = dyn_cast<PointerType>(M->getType()); +    if (PTy == 0) return failure(true); +    MethodType *MTy = dyn_cast<MethodType>(PTy->getValueType()); +    if (MTy == 0) return failure(true); + +    vector<Value *> Params; +    const MethodType::ParamTypes &PL = MTy->getParamTypes(); +    vector<unsigned> &args = *Raw.VarArgs; + +    BasicBlock *Normal, *Except; + +    if (!MTy->isVarArg()) { +      if (Raw.NumOperands < 3) return failure(true); + +      Normal = cast<BasicBlock>(getValue(Type::LabelTy, Raw.Arg2)); +      Except = cast<BasicBlock>(getValue(Type::LabelTy, args[0])); + +      MethodType::ParamTypes::const_iterator It = PL.begin(); +      for (unsigned i = 1; i < args.size(); i++) { +	if (It == PL.end()) return failure(true); +	// TODO: Check getValue for null! +	Params.push_back(getValue(*It++, args[i])); +      } + +      if (It != PL.end()) return failure(true); +    } else { +      if (args.size() < 4) return failure(true); + +      Normal = cast<BasicBlock>(getValue(Type::LabelTy, args[0])); +      Except = cast<BasicBlock>(getValue(Type::LabelTy, args[2])); -      vector<unsigned> &args = *Raw.VarArgs;        if ((args.size() & 1) != 0)  	return failure(true);  // Must be pairs of type/value -      for (unsigned i = 0; i < args.size(); i+=2) { +      for (unsigned i = 4; i < args.size(); i+=2) {  	// TODO: Check getValue for null!  	Params.push_back(getValue(getType(args[i]), args[i+1]));        } -      delete Raw.VarArgs;      } -    Res = new CallInst(M, Params); +    delete Raw.VarArgs; +    Res = new InvokeInst(M, Normal, Except, Params);      return false;    }    case Instruction::Malloc:  | 
