+ Result = new CallInst(F, Params);
+ break;
+ }
+ case Instruction::Invoke: {
+ if (Args.size() < 3) throw std::string("Invalid invoke instruction!");
+ Value *F = getValue(RI.Type, Args[0]);
+
+ // Check to make sure we have a pointer to function type
+ const PointerType *PTy = dyn_cast<PointerType>(F->getType());
+ if (PTy == 0) throw std::string("Invoke to non function pointer value!");
+ const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
+ if (FTy == 0) throw std::string("Invoke to non function pointer value!");
+
+ std::vector<Value *> Params;
+ BasicBlock *Normal, *Except;
+
+ if (!FTy->isVarArg()) {
+ Normal = getBasicBlock(Args[1]);
+ Except = getBasicBlock(Args[2]);
+
+ FunctionType::param_iterator It = FTy->param_begin();
+ for (unsigned i = 3, e = Args.size(); i != e; ++i) {
+ if (It == FTy->param_end())
+ throw std::string("Invalid invoke instruction!");
+ Params.push_back(getValue(getTypeSlot(*It++), Args[i]));
+ }
+ if (It != FTy->param_end())
+ throw std::string("Invalid invoke instruction!");
+ } else {
+ Args.erase(Args.begin(), Args.begin()+1+hasVarArgCallPadding);
+
+ unsigned FirstVariableArgument;
+ if (!hasVarArgCallPadding) {
+ Normal = getBasicBlock(Args[0]);
+ Except = getBasicBlock(Args[1]);
+
+ FirstVariableArgument = FTy->getNumParams()+2;
+ for (unsigned i = 2; i != FirstVariableArgument; ++i)
+ Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
+ Args[i]));
+
+ } else {
+ if (Args.size() < 4) throw std::string("Invalid invoke instruction!");
+ if (Args[0] != Type::LabelTyID || Args[2] != Type::LabelTyID)
+ throw std::string("Invalid invoke instruction!");
+ Normal = getBasicBlock(Args[1]);
+ Except = getBasicBlock(Args[3]);
+
+ FirstVariableArgument = 4;
+ }
+
+ if (Args.size()-FirstVariableArgument & 1) // Must be pairs of type/value
+ throw std::string("Invalid invoke instruction!");
+
+ for (unsigned i = FirstVariableArgument; i < Args.size(); i += 2)
+ Params.push_back(getValue(Args[i], Args[i+1]));
+ }
+
+ Result = new InvokeInst(F, Normal, Except, Params);
+ break;