* New revised variable argument handling support
[oota-llvm.git] / lib / Bytecode / Reader / ReaderWrappers.cpp
1 //===- ReaderWrappers.cpp - Parse bytecode from file or buffer  -----------===//
2 //
3 // This file implements loading and parsing a bytecode file and parsing a
4 // bytecode module from a given buffer.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "ReaderInternals.h"
9 #include "llvm/Module.h"
10 #include "llvm/Instructions.h"
11 #include "Support/StringExtras.h"
12 #include "Config/fcntl.h"
13 #include <sys/stat.h>
14 #include "Config/unistd.h"
15 #include "Config/sys/mman.h"
16
17 //===----------------------------------------------------------------------===//
18 // BytecodeFileReader - Read from an mmap'able file descriptor.
19 //
20
21 namespace {
22   /// FDHandle - Simple handle class to make sure a file descriptor gets closed
23   /// when the object is destroyed.
24   ///
25   class FDHandle {
26     int FD;
27   public:
28     FDHandle(int fd) : FD(fd) {}
29     operator int() const { return FD; }
30     ~FDHandle() {
31       if (FD != -1) close(FD);
32     }
33   };
34
35   /// BytecodeFileReader - parses a bytecode file from a file
36   ///
37   class BytecodeFileReader : public BytecodeParser {
38   private:
39     unsigned char *Buffer;
40     int Length;
41
42     BytecodeFileReader(const BytecodeFileReader&); // Do not implement
43     void operator=(const BytecodeFileReader &BFR); // Do not implement
44
45   public:
46     BytecodeFileReader(const std::string &Filename);
47     ~BytecodeFileReader();
48   };
49 }
50
51 BytecodeFileReader::BytecodeFileReader(const std::string &Filename) {
52   FDHandle FD = open(Filename.c_str(), O_RDONLY);
53   if (FD == -1)
54     throw std::string("Error opening file!");
55
56   // Stat the file to get its length...
57   struct stat StatBuf;
58   if (fstat(FD, &StatBuf) == -1 || StatBuf.st_size == 0)
59     throw std::string("Error stat'ing file!");
60
61   // mmap in the file all at once...
62   Length = StatBuf.st_size;
63   Buffer = (unsigned char*)mmap(0, Length, PROT_READ, MAP_PRIVATE, FD, 0);
64
65   if (Buffer == (unsigned char*)MAP_FAILED)
66     throw std::string("Error mmapping file!");
67
68   try {
69     // Parse the bytecode we mmapped in
70     ParseBytecode(Buffer, Length, Filename);
71   } catch (...) {
72     munmap((char*)Buffer, Length);
73     throw;
74   }
75 }
76
77 BytecodeFileReader::~BytecodeFileReader() {
78   // Unmmap the bytecode...
79   munmap((char*)Buffer, Length);
80 }
81
82 //===----------------------------------------------------------------------===//
83 // BytecodeBufferReader - Read from a memory buffer
84 //
85
86 namespace {
87   /// BytecodeBufferReader - parses a bytecode file from a buffer
88   ///
89   class BytecodeBufferReader : public BytecodeParser {
90   private:
91     const unsigned char *Buffer;
92     bool MustDelete;
93
94     BytecodeBufferReader(const BytecodeBufferReader&); // Do not implement
95     void operator=(const BytecodeBufferReader &BFR);   // Do not implement
96
97   public:
98     BytecodeBufferReader(const unsigned char *Buf, unsigned Length,
99                          const std::string &ModuleID);
100     ~BytecodeBufferReader();
101
102   };
103 }
104
105 BytecodeBufferReader::BytecodeBufferReader(const unsigned char *Buf,
106                                            unsigned Length,
107                                            const std::string &ModuleID)
108 {
109   // If not aligned, allocate a new buffer to hold the bytecode...
110   const unsigned char *ParseBegin = 0;
111   if ((intptr_t)Buf & 3) {
112     Buffer = new unsigned char[Length+4];
113     unsigned Offset = 4 - ((intptr_t)Buffer & 3);   // Make sure it's aligned
114     ParseBegin = Buffer + Offset;
115     memcpy((unsigned char*)ParseBegin, Buf, Length);    // Copy it over
116     MustDelete = true;
117   } else {
118     // If we don't need to copy it over, just use the caller's copy
119     ParseBegin = Buffer = Buf;
120     MustDelete = false;
121   }
122   try {
123     ParseBytecode(ParseBegin, Length, ModuleID);
124   } catch (...) {
125     if (MustDelete) delete [] Buffer;
126     throw;
127   }
128 }
129
130 BytecodeBufferReader::~BytecodeBufferReader() {
131   if (MustDelete) delete [] Buffer;
132 }
133
134 //===----------------------------------------------------------------------===//
135 //  BytecodeStdinReader - Read bytecode from Standard Input
136 //
137
138 namespace {
139   /// BytecodeStdinReader - parses a bytecode file from stdin
140   /// 
141   class BytecodeStdinReader : public BytecodeParser {
142   private:
143     std::vector<unsigned char> FileData;
144     unsigned char *FileBuf;
145
146     BytecodeStdinReader(const BytecodeStdinReader&); // Do not implement
147     void operator=(const BytecodeStdinReader &BFR);  // Do not implement
148
149   public:
150     BytecodeStdinReader();
151   };
152 }
153
154 BytecodeStdinReader::BytecodeStdinReader() {
155   int BlockSize;
156   unsigned char Buffer[4096*4];
157
158   // Read in all of the data from stdin, we cannot mmap stdin...
159   while ((BlockSize = read(0 /*stdin*/, Buffer, 4096*4))) {
160     if (BlockSize == -1)
161       throw std::string("Error reading from stdin!");
162     
163     FileData.insert(FileData.end(), Buffer, Buffer+BlockSize);
164   }
165
166   if (FileData.empty())
167     throw std::string("Standard Input empty!");
168
169   FileBuf = &FileData[0];
170   ParseBytecode(FileBuf, FileData.size(), "<stdin>");
171 }
172
173 //===----------------------------------------------------------------------===//
174 //  Varargs transmogrification code...
175 //
176
177 // CheckVarargs - This is used to automatically translate old-style varargs to
178 // new style varargs for backwards compatibility.
179 static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
180   Module *M = MP->getModule();
181   
182   // Check to see if va_start takes arguments...
183   Function *F = M->getNamedFunction("llvm.va_start");
184   if (F == 0) return MP;  // No varargs use, just return.
185
186   if (F->getFunctionType()->getNumParams() == 0)
187     return MP;  // Modern varargs processing, just return.
188
189   // If we get to this point, we know that we have an old-style module.
190   // Materialize the whole thing to perform the rewriting.
191   MP->materializeModule();
192
193   // If the user is making use of obsolete varargs intrinsics, adjust them for
194   // the user.
195   if (Function *F = M->getNamedFunction("llvm.va_start")) {
196     assert(F->asize() == 1 && "Obsolete va_start takes 1 argument!");
197         
198     const Type *RetTy = F->getFunctionType()->getParamType(0);
199     RetTy = cast<PointerType>(RetTy)->getElementType();
200     Function *NF = M->getOrInsertFunction("llvm.va_start", RetTy, 0);
201         
202     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
203       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
204         Value *V = new CallInst(NF, "", CI);
205         new StoreInst(V, CI->getOperand(1), CI);
206         CI->getParent()->getInstList().erase(CI);
207       }
208     F->setName("");
209   }
210
211   if (Function *F = M->getNamedFunction("llvm.va_end")) {
212     assert(F->asize() == 1 && "Obsolete va_end takes 1 argument!");
213     const Type *ArgTy = F->getFunctionType()->getParamType(0);
214     ArgTy = cast<PointerType>(ArgTy)->getElementType();
215     Function *NF = M->getOrInsertFunction("llvm.va_end", Type::VoidTy,
216                                                   ArgTy, 0);
217         
218     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
219       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
220         Value *V = new LoadInst(CI->getOperand(1), "", CI);
221         new CallInst(NF, V, "", CI);
222         CI->getParent()->getInstList().erase(CI);
223       }
224     F->setName("");
225   }
226       
227   if (Function *F = M->getNamedFunction("llvm.va_copy")) {
228     assert(F->asize() == 2 && "Obsolete va_copy takes 2 argument!");
229     const Type *ArgTy = F->getFunctionType()->getParamType(0);
230     ArgTy = cast<PointerType>(ArgTy)->getElementType();
231     Function *NF = M->getOrInsertFunction("llvm.va_copy", ArgTy,
232                                                   ArgTy, 0);
233         
234     for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
235       if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
236         Value *V = new CallInst(NF, CI->getOperand(2), "", CI);
237         new StoreInst(V, CI->getOperand(1), CI);
238         CI->getParent()->getInstList().erase(CI);
239       }
240     F->setName("");
241   }
242   return MP;
243 }
244
245
246 //===----------------------------------------------------------------------===//
247 // Wrapper functions
248 //===----------------------------------------------------------------------===//
249
250 /// getBytecodeBufferModuleProvider - lazy function-at-a-time loading from a
251 /// buffer
252 ModuleProvider* 
253 getBytecodeBufferModuleProvider(const unsigned char *Buffer, unsigned Length,
254                                 const std::string &ModuleID) {
255   return CheckVarargs(new BytecodeBufferReader(Buffer, Length, ModuleID));
256 }
257
258 /// ParseBytecodeBuffer - Parse a given bytecode buffer
259 ///
260 Module *ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
261                             const std::string &ModuleID, std::string *ErrorStr){
262   try {
263     std::auto_ptr<ModuleProvider>
264       AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID));
265     return AMP->releaseModule();
266   } catch (std::string &err) {
267     if (ErrorStr) *ErrorStr = err;
268     return 0;
269   }
270 }
271
272 /// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
273 ///
274 ModuleProvider *getBytecodeModuleProvider(const std::string &Filename) {
275   if (Filename != std::string("-"))        // Read from a file...
276     return CheckVarargs(new BytecodeFileReader(Filename));
277   else                                     // Read from stdin
278     return CheckVarargs(new BytecodeStdinReader());
279 }
280
281 /// ParseBytecodeFile - Parse the given bytecode file
282 ///
283 Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
284   try {
285     std::auto_ptr<ModuleProvider> AMP(getBytecodeModuleProvider(Filename));
286     return AMP->releaseModule();
287   } catch (std::string &err) {
288     if (ErrorStr) *ErrorStr = err;
289     return 0;
290   }
291 }