1 /**
2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This file contains data structure to handle LLVM Memory Buffers.
7 */
8 module llvm_hiwrap.buffer;
9 
10 import llvm_hiwrap.types : LxMessage;
11 import llvm_hiwrap.util : toD;
12 
13 struct MemoryBuffer {
14     import std.string : toStringz;
15     import llvm;
16 
17     LLVMMemoryBufferRef lx;
18 
19     // TODO move to llvm_hiwrap.llvm_io
20     static BufferFromFileResult fromFile(string path) {
21         LLVMMemoryBufferRef buf;
22         LxMessage msg;
23 
24         const(char)* p = path.toStringz;
25         LLVMBool success = LLVMCreateMemoryBufferWithContentsOfFile(p, &buf, &msg.rawPtr);
26         return BufferFromFileResult(MemoryBuffer(buf), success == 0, msg.toD);
27     }
28 
29     static MemoryBufferFromMemory fromMemory(const(ubyte)[] region, string buffer_name) {
30         const(char)* name = buffer_name.toStringz;
31         LLVMMemoryBufferRef buf = LLVMCreateMemoryBufferWithMemoryRange(
32                 cast(const(char)*) region.ptr, region.length, name, LLVMBool(false));
33         return MemoryBufferFromMemory(region, MemoryBuffer(buf));
34     }
35 
36     static MemoryBuffer fromMemoryCopy(const(ubyte)[] region, string buffer_name) {
37         const(char)* name = buffer_name.toStringz;
38         LLVMMemoryBufferRef buf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
39                 cast(const(char)*) region.ptr, region.length, name);
40         return MemoryBuffer(buf);
41     }
42 
43     @disable this(this);
44 
45     ~this() {
46         LLVMDisposeMemoryBuffer(lx);
47     }
48 
49     size_t length() {
50         return LLVMGetBufferSize(lx);
51     }
52 
53     const(ubyte)[] slice() {
54         const(ubyte)* begin = cast(const(ubyte)*) LLVMGetBufferStart(lx);
55         return begin[0 .. this.length];
56     }
57 }
58 
59 struct MemoryBufferFromMemory {
60     // Keep a reference around to the memory in case it is allocated by the GC.
61     private const(ubyte)[] region;
62 
63     MemoryBuffer buffer;
64     alias buffer this;
65 
66     @disable this(this);
67 }
68 
69 private:
70 
71 struct BufferFromFileResult {
72     private MemoryBuffer value_;
73     bool isValid;
74     string errorMsg;
75 
76     MemoryBuffer value() {
77         assert(isValid);
78         auto lx = value_.lx;
79         value_.lx = null;
80         return MemoryBuffer(lx);
81     }
82 }