diff options
Diffstat (limited to 'lib/Bytecode/Reader')
-rw-r--r-- | lib/Bytecode/Reader/ConstantReader.cpp | 10 | ||||
-rw-r--r-- | lib/Bytecode/Reader/InstructionReader.cpp | 54 |
2 files changed, 41 insertions, 23 deletions
diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index 2994128f7d..e367d02e7c 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -33,15 +33,15 @@ bool BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf, const Type *RetType = getType(Typ); if (RetType == 0) return true; - MethodType::ParamTypes Params; + unsigned NumParams; + if (read_vbr(Buf, EndBuf, NumParams)) return true; - if (read_vbr(Buf, EndBuf, Typ)) return true; - while (Typ) { + MethodType::ParamTypes Params; + while (NumParams--) { + if (read_vbr(Buf, EndBuf, Typ)) return true; const Type *Ty = getType(Typ); if (Ty == 0) return true; Params.push_back(Ty); - - if (read_vbr(Buf, EndBuf, Typ)) return true; } Val = MethodType::getMethodType(RetType, Params); diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 3af40f2d81..f1dcf08e79 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -196,30 +196,48 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, Method *M = (Method*)getValue(Raw.Ty, Raw.Arg1); if (M == 0) return true; + vector<Value *> Params; const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes(); - MethodType::ParamTypes::const_iterator It = PL.begin(); - vector<Value *> Params; - switch (Raw.NumOperands) { - case 0: cerr << "Invalid call instruction encountered!\n"; - return true; - case 1: break; - case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; - case 3: Params.push_back(getValue(*It++, Raw.Arg2)); - if (It == PL.end()) return true; - Params.push_back(getValue(*It++, Raw.Arg3)); break; - default: - Params.push_back(getValue(*It++, Raw.Arg2)); - { - vector<unsigned> &args = *Raw.VarArgs; - for (unsigned i = 0; i < args.size(); i++) { - if (It == PL.end()) return true; - Params.push_back(getValue(*It++, args[i])); + if (!M->getType()->isMethodType()->isVarArg()) { + MethodType::ParamTypes::const_iterator It = PL.begin(); + + switch (Raw.NumOperands) { + case 0: cerr << "Invalid call instruction encountered!\n"; + return true; + case 1: break; + case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; + case 3: Params.push_back(getValue(*It++, Raw.Arg2)); + if (It == PL.end()) return true; + Params.push_back(getValue(*It++, Raw.Arg3)); break; + default: + Params.push_back(getValue(*It++, Raw.Arg2)); + { + vector<unsigned> &args = *Raw.VarArgs; + for (unsigned i = 0; i < args.size(); i++) { + if (It == PL.end()) return true; + // TODO: Check getValue for null! + Params.push_back(getValue(*It++, args[i])); + } } + delete Raw.VarArgs; + } + if (It != PL.end()) return 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)); + + vector<unsigned> &args = *Raw.VarArgs; + if ((args.size() & 1) != 0) return true; // Must be pairs of type/value + for (unsigned i = 0; i < args.size(); i+=2) { + Value *Ty = getValue(Type::TypeTy, args[i]); + if (!Ty) return true; + // TODO: Check getValue for null! + Params.push_back(getValue(Ty->castTypeAsserting(), args[i+1])); } delete Raw.VarArgs; } - if (It != PL.end()) return true; Res = new CallInst(M, Params); return false; |