summaryrefslogtreecommitdiff
path: root/include/llvm/Bytecode
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-06-06 20:29:01 +0000
committerChris Lattner <sabre@nondot.org>2001-06-06 20:29:01 +0000
commit009505452b713ed2e3a8e99c5545a6e721c65495 (patch)
tree136a71c5b87bdf534d1f20a67558b49226b5a4d6 /include/llvm/Bytecode
parent8d0afd3d32d1d67f9aa5df250a1d6955aa8f1ac9 (diff)
downloadllvm-009505452b713ed2e3a8e99c5545a6e721c65495.tar.gz
llvm-009505452b713ed2e3a8e99c5545a6e721c65495.tar.bz2
llvm-009505452b713ed2e3a8e99c5545a6e721c65495.tar.xz
Initial revision
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Bytecode')
-rw-r--r--include/llvm/Bytecode/Format.h33
-rw-r--r--include/llvm/Bytecode/Primitives.h237
-rw-r--r--include/llvm/Bytecode/Reader.h24
-rw-r--r--include/llvm/Bytecode/Writer.h25
4 files changed, 319 insertions, 0 deletions
diff --git a/include/llvm/Bytecode/Format.h b/include/llvm/Bytecode/Format.h
new file mode 100644
index 0000000000..a87f8d18a6
--- /dev/null
+++ b/include/llvm/Bytecode/Format.h
@@ -0,0 +1,33 @@
+//===-- llvm/Bytecode/Format.h - VM bytecode file format info ----*- C++ -*--=//
+//
+// This header defines intrinsic constants that are useful to libraries that
+// need to hack on bytecode files directly, like the reader and writer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BYTECODE_FORMAT_H
+#define LLVM_BYTECODE_FORMAT_H
+
+class BytecodeFormat { // Throw the constants into a poorman's namespace...
+ BytecodeFormat(); // do not implement
+public:
+
+ // ID Numbers that are used in bytecode files...
+ enum FileBlockIDs {
+ // File level identifiers...
+ Module = 0x01,
+
+ // Module subtypes:
+ Method = 0x11,
+ ConstantPool,
+ SymbolTable,
+ ModuleGlobalInfo,
+
+ // Method subtypes:
+ MethodInfo = 0x21,
+ // Can also have ConstantPool block
+ // Can also have SymbolTable block
+ BasicBlock = 0x31, // May contain many basic blocks
+ };
+};
+#endif
diff --git a/include/llvm/Bytecode/Primitives.h b/include/llvm/Bytecode/Primitives.h
new file mode 100644
index 0000000000..f4b232b368
--- /dev/null
+++ b/include/llvm/Bytecode/Primitives.h
@@ -0,0 +1,237 @@
+//===-- llvm/Bytecode/Primitives.h - Bytecode file format prims --*- C++ -*--=//
+//
+// This header defines some basic functions for reading and writing basic
+// primitive types to a bytecode stream.
+//
+// Using the routines defined in this file does not require linking to any
+// libraries, as all of the services are small self contained units that are to
+// be inlined as neccesary.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BYTECODE_PRIMITIVES_H
+#define LLVM_BYTECODE_PRIMITIVES_H
+
+#include "llvm/Tools/DataTypes.h"
+#include <string>
+#include <vector>
+
+//===----------------------------------------------------------------------===//
+// Reading Primitives
+//===----------------------------------------------------------------------===//
+
+static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
+ unsigned &Result) {
+ if (Buf+4 > EndBuf) return true;
+#ifdef LITTLE_ENDIAN
+ Result = *(unsigned*)Buf;
+#else
+ Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24);
+#endif
+ Buf += 4;
+ return false;
+}
+
+static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
+ uint64_t &Result) {
+ if (Buf+8 > EndBuf) return true;
+
+#ifdef LITTLE_ENDIAN
+ Result = *(uint64_t*)Buf;
+#else
+ Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24) |
+ ((uint64_t)(Buf[4] | (Buf[5] << 8) | (Buf[6] << 16) | (Buf[7] << 24)) <<32);
+#endif
+ Buf += 8;
+ return false;
+}
+
+static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
+ int &Result) {
+ return read(Buf, EndBuf, (unsigned &)Result);
+}
+
+static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
+ int64_t &Result) {
+ return read(Buf, EndBuf, (uint64_t &)Result);
+}
+
+
+// read_vbr - Read an unsigned integer encoded in variable bitrate format.
+//
+static inline bool read_vbr(const unsigned char *&Buf,
+ const unsigned char *EndBuf, unsigned &Result) {
+ unsigned Shift = Result = 0;
+
+ do {
+ Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
+ Shift += 7;
+ } while (Buf[-1] & 0x80 && Buf < EndBuf);
+
+ return Buf > EndBuf;
+}
+
+static inline bool read_vbr(const unsigned char *&Buf,
+ const unsigned char *EndBuf, uint64_t &Result) {
+ unsigned Shift = 0; Result = 0;
+
+ do {
+ Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
+ Shift += 7;
+ } while (Buf[-1] & 0x80 && Buf < EndBuf);
+ return Buf > EndBuf;
+}
+
+// read_vbr (signed) - Read a signed number stored in sign-magnitude format
+static inline bool read_vbr(const unsigned char *&Buf,
+ const unsigned char *EndBuf, int &Result) {
+ unsigned R;
+ if (read_vbr(Buf, EndBuf, R)) return true;
+ if (R & 1)
+ Result = -(int)(R >> 1);
+ else
+ Result = (int)(R >> 1);
+
+ return false;
+}
+
+
+static inline bool read_vbr(const unsigned char *&Buf,
+ const unsigned char *EndBuf, int64_t &Result) {
+ uint64_t R;
+ if (read_vbr(Buf, EndBuf, R)) return true;
+ if (R & 1)
+ Result = -(int64_t)(R >> 1);
+ else
+ Result = (int64_t)(R >> 1);
+
+ return false;
+}
+
+// align32 - Round up to multiple of 32 bits...
+static inline bool align32(const unsigned char *&Buf,
+ const unsigned char *EndBuf) {
+ Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
+ return Buf > EndBuf;
+}
+
+static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
+ string &Result, bool Aligned = true) {
+ unsigned Size;
+ if (read_vbr(Buf, EndBuf, Size)) return true; // Failure reading size?
+ if (Buf+Size > EndBuf) return true; // Size invalid?
+
+ Result = string((char*)Buf, Size);
+ Buf += Size;
+
+ if (Aligned) // If we should stay aligned do so...
+ if (align32(Buf, EndBuf)) return true; // Failure aligning?
+
+ return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Writing Primitives
+//===----------------------------------------------------------------------===//
+
+// output - If a position is specified, it must be in the valid portion of the
+// string... note that this should be inlined always so only the relevant IF
+// body should be included...
+//
+static inline void output(unsigned i, vector<unsigned char> &Out, int pos = -1){
+#ifdef LITTLE_ENDIAN
+ if (pos == -1)
+ Out.insert(Out.end(), (unsigned char*)&i, (unsigned char*)&i+4);
+ else
+ *(unsigned*)&Out[pos] = i;
+#else
+ if (pos == -1) { // Be endian clean, little endian is our friend
+ Out.push_back((unsigned char)i);
+ Out.push_back((unsigned char)(i >> 8));
+ Out.push_back((unsigned char)(i >> 16));
+ Out.push_back((unsigned char)(i >> 24));
+ } else {
+ Out[pos ] = (unsigned char)i;
+ Out[pos+1] = (unsigned char)(i >> 8);
+ Out[pos+2] = (unsigned char)(i >> 16);
+ Out[pos+3] = (unsigned char)(i >> 24);
+ }
+#endif
+}
+
+static inline void output(int i, vector<unsigned char> &Out) {
+ output((unsigned)i, Out);
+}
+
+// output_vbr - Output an unsigned value, by using the least number of bytes
+// possible. This is useful because many of our "infinite" values are really
+// very small most of the time... but can be large a few times...
+//
+// Data format used: If you read a byte with the night bit set, use the low
+// seven bits as data and then read another byte...
+//
+// Note that using this may cause the output buffer to become unaligned...
+//
+static inline void output_vbr(uint64_t i, vector<unsigned char> &out) {
+ while (1) {
+ if (i < 0x80) { // done?
+ out.push_back((unsigned char)i); // We know the high bit is clear...
+ return;
+ }
+
+ // Nope, we are bigger than a character, output the next 7 bits and set the
+ // high bit to say that there is more coming...
+ out.push_back(0x80 | (i & 0x7F));
+ i >>= 7; // Shift out 7 bits now...
+ }
+}
+
+static inline void output_vbr(unsigned i, vector<unsigned char> &out) {
+ while (1) {
+ if (i < 0x80) { // done?
+ out.push_back((unsigned char)i); // We know the high bit is clear...
+ return;
+ }
+
+ // Nope, we are bigger than a character, output the next 7 bits and set the
+ // high bit to say that there is more coming...
+ out.push_back(0x80 | (i & 0x7F));
+ i >>= 7; // Shift out 7 bits now...
+ }
+}
+
+static inline void output_vbr(int64_t i, vector<unsigned char> &out) {
+ if (i < 0)
+ output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit...
+ else
+ output_vbr((uint64_t)i << 1, out); // Low order bit is clear.
+}
+
+
+static inline void output_vbr(int i, vector<unsigned char> &out) {
+ if (i < 0)
+ output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit...
+ else
+ output_vbr((unsigned)i << 1, out); // Low order bit is clear.
+}
+
+// align32 - emit the minimal number of bytes that will bring us to 32 bit
+// alignment...
+//
+static inline void align32(vector<unsigned char> &Out) {
+ int NumPads = (4-(Out.size() & 3)) & 3; // Bytes to get padding to 32 bits
+ while (NumPads--) Out.push_back((unsigned char)0xAB);
+}
+
+static inline void output(const string &s, vector<unsigned char> &Out,
+ bool Aligned = true) {
+ unsigned Len = s.length();
+ output_vbr(Len, Out); // Strings may have an arbitrary length...
+ Out.insert(Out.end(), s.begin(), s.end());
+
+ if (Aligned)
+ align32(Out); // Make sure we are now aligned...
+}
+
+#endif
diff --git a/include/llvm/Bytecode/Reader.h b/include/llvm/Bytecode/Reader.h
new file mode 100644
index 0000000000..17ddfc8fb8
--- /dev/null
+++ b/include/llvm/Bytecode/Reader.h
@@ -0,0 +1,24 @@
+//===-- llvm/Bytecode/Reader.h - Reader for VM bytecode files ----*- C++ -*--=//
+//
+// This functionality is implemented by the lib/BytecodeReader library.
+// This library is used to read VM bytecode files from an iostream.
+//
+// Note that performance of this library is _crucial_ for performance of the
+// JIT type applications, so we have designed the bytecode format to support
+// quick reading.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BYTECODE_READER_H
+#define LLVM_BYTECODE_READER_H
+
+#include <string>
+
+class Module;
+
+// Parse and return a class...
+//
+Module *ParseBytecodeFile(const string &Filename);
+Module *ParseBytecodeBuffer(const char *Buffer, unsigned BufferSize);
+
+#endif
diff --git a/include/llvm/Bytecode/Writer.h b/include/llvm/Bytecode/Writer.h
new file mode 100644
index 0000000000..e28ea77f07
--- /dev/null
+++ b/include/llvm/Bytecode/Writer.h
@@ -0,0 +1,25 @@
+//===-- llvm/Bytecode/Writer.h - Writer for VM bytecode files ----*- C++ -*--=//
+//
+// This functionality is implemented by the lib/BytecodeWriter library.
+// This library is used to write VM bytecode files to an iostream. First, you
+// have to make a BytecodeStream object, which you can then put a class into
+// by using operator <<.
+//
+// This library uses the Analysis library to figure out offsets for
+// variables in the method tables...
+//
+// Note that performance of this library is not as crucial as performance of the
+// bytecode reader (which is to be used in JIT type applications), so we have
+// designed the bytecode format to support quick reading.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BYTECODE_WRITER_H
+#define LLVM_BYTECODE_WRITER_H
+
+#include <iostream.h>
+
+class Module;
+void WriteBytecodeToFile(const Module *C, ostream &Out);
+
+#endif