1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

Adding bindings for memory buffers and module providers. Switching

to exceptions rather than variants for error handling in Ocaml.

llvm-svn: 45226
This commit is contained in:
Gordon Henriksen 2007-12-19 22:30:40 +00:00
parent f93ea63eaa
commit 46137f1e2e
16 changed files with 350 additions and 154 deletions

View File

@ -98,6 +98,7 @@
9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitcodeWriterPass.cpp; sourceTree = "<group>"; };
9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ValueEnumerator.cpp; sourceTree = "<group>"; };
9F68EB260C77AD2C004AA152 /* ValueEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ValueEnumerator.h; sourceTree = "<group>"; };
9F6B2CC00D0F6E56000F00FD /* bitreader.ml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bitreader.ml; sourceTree = "<group>"; };
9F7793460C73BC2000551F9C /* CodeGenPrepare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenPrepare.cpp; sourceTree = "<group>"; };
9F7793470C73BC2000551F9C /* GVN.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GVN.cpp; sourceTree = "<group>"; };
9F7793480C73BC2000551F9C /* GVNPRE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GVNPRE.cpp; sourceTree = "<group>"; };
@ -1241,6 +1242,7 @@
isa = PBXGroup;
children = (
9F7C2C4F0CB9496C00498408 /* analysis.ml */,
9F6B2CC00D0F6E56000F00FD /* bitreader.ml */,
9F7C2C520CB9496C00498408 /* bitwriter.ml */,
9F7C2C5D0CB9496C00498408 /* vmcore.ml */,
);

View File

@ -37,7 +37,7 @@ CAMLprim value llvm_verify_module(LLVMModuleRef M) {
Store_field(Option, 0, String);
}
LLVMDisposeVerifierMessage(Message);
LLVMDisposeMessage(Message);
CAMLreturn(Option);
}

View File

@ -16,31 +16,46 @@
#include "caml/alloc.h"
#include "caml/mlvalues.h"
#include "caml/memory.h"
#include <stdio.h>
/* Can't use the recommended caml_named_value mechanism for backwards
compatibility reasons. This is largely equivalent. */
static value llvm_bitreader_error_exn;
CAMLprim value llvm_register_bitreader_exns(value Error) {
llvm_bitreader_error_exn = Field(Error, 0);
register_global_root(&llvm_bitreader_error_exn);
return Val_unit;
}
void llvm_raise(value Prototype, char *Message);
/*===-- Modules -----------------------------------------------------------===*/
/* string -> bitreader_result
/* Llvm.llmemorybuffer -> Llvm.module */
CAMLprim value llvm_get_module_provider(LLVMMemoryBufferRef MemBuf) {
CAMLparam0();
CAMLlocal2(Variant, MessageVal);
char *Message;
LLVMModuleProviderRef MP;
if (LLVMGetBitcodeModuleProvider(MemBuf, &MP, &Message))
llvm_raise(llvm_bitreader_error_exn, Message);
CAMLreturn((value) MemBuf);
}
type bitreader_result =
| Bitreader_success of Llvm.llmodule
| Bitreader_failure of string
*/
CAMLprim value llvm_read_bitcode_file(value Path) {
/* Llvm.llmemorybuffer -> Llvm.llmodule */
CAMLprim value llvm_parse_bitcode(LLVMMemoryBufferRef MemBuf) {
CAMLparam0();
CAMLlocal2(Variant, MessageVal);
LLVMModuleRef M;
char *Message;
CAMLparam1(Path);
CAMLlocal2(Variant, MessageVal);
if (LLVMReadBitcodeFromFile(String_val(Path), &M, &Message)) {
MessageVal = copy_string(Message);
LLVMDisposeBitcodeReaderMessage(Message);
Variant = alloc(1, 1);
Field(Variant, 0) = MessageVal;
} else {
Variant = alloc(1, 0);
Field(Variant, 0) = Val_op(M);
}
if (LLVMParseBitcode(MemBuf, &M, &Message))
llvm_raise(llvm_bitreader_error_exn, Message);
CAMLreturn(Variant);
CAMLreturn((value) M);
}

View File

@ -8,10 +8,12 @@
*===----------------------------------------------------------------------===*)
type bitreader_result =
| Bitreader_success of Llvm.llmodule
| Bitreader_failure of string
exception Error of string
external register_exns : exn -> unit = "llvm_register_bitreader_exns"
let _ = register_exns (Error "")
external read_bitcode_file : string -> bitreader_result
= "llvm_read_bitcode_file"
external get_module_provider : Llvm.llmemorybuffer -> Llvm.llmoduleprovider
= "llvm_get_module_provider"
external parse_bitcode : Llvm.llmemorybuffer -> Llvm.llmodule
= "llvm_parse_bitcode"

View File

@ -13,13 +13,18 @@
*===----------------------------------------------------------------------===*)
type bitreader_result =
| Bitreader_success of Llvm.llmodule
| Bitreader_failure of string
exception Error of string
(** [read_bitcode_file path] reads the bitcode for a new module [m] from the
file at [path]. Returns [Success m] if successful, and [Failure msg]
otherwise, where [msg] is a description of the error encountered.
See the function [llvm::getBitcodeModuleProvider]. **)
external get_module_provider : Llvm.llmemorybuffer -> Llvm.llmoduleprovider
= "llvm_get_module_provider"
(** [read_bitcode_file path] reads the bitcode for module [m] from the file at
[path]. Returns [Reader_success m] if successful, and [Reader_failure msg]
otherwise, where [msg] is a description of the error encountered. **)
external read_bitcode_file : string -> bitreader_result
= "llvm_read_bitcode_file"
(** [parse_bitcode mb] parses the bitcode for a new module [m] from the memory
buffer [mb]. Returns [Success m] if successful, and [Failure msg] otherwise,
where [msg] is a description of the error encountered.
See the function [llvm::ParseBitcodeFile]. **)
external parse_bitcode : Llvm.llmemorybuffer -> Llvm.llmodule
= "llvm_parse_bitcode"

View File

@ -15,6 +15,7 @@ type llvalue
type llbasicblock
type llbuilder
type llmoduleprovider
type llmemorybuffer
type type_kind =
Void_type
@ -84,6 +85,11 @@ type real_predicate =
| Fcmp_une
| Fcmp_true
exception IoError of string
external register_exns : exn -> unit = "llvm_register_core_exns"
let _ = register_exns (IoError "")
(*===-- Modules -----------------------------------------------------------===*)
@ -432,10 +438,21 @@ external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
(*===-- Module providers --------------------------------------------------===*)
external create_module_provider : llmodule -> llmoduleprovider
= "LLVMCreateModuleProviderForExistingModule"
external dispose_module_provider : llmoduleprovider -> unit
= "llvm_dispose_module_provider"
module ModuleProvider = struct
external create : llmodule -> llmoduleprovider
= "LLVMCreateModuleProviderForExistingModule"
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
end
(*===-- Memory buffers ----------------------------------------------------===*)
module MemoryBuffer = struct
external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file"
external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin"
external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
end
(*===-- Non-Externs -------------------------------------------------------===*)

View File

@ -40,9 +40,14 @@ type llbasicblock
class. **)
type llbuilder
(** Used to provide a module to JIT or interpreter. **)
(** Used to provide a module to JIT or interpreter.
See the [llvm::ModuleProvider] class. **)
type llmoduleprovider
(** Used to efficiently handle large buffers of read-only binary data.
See the [llvm::MemoryBuffer] class. **)
type llmemorybuffer
(** The kind of an [lltype], the result of [classify_type ty]. See the
[llvm::Type::TypeID] enumeration. **)
type type_kind =
@ -129,6 +134,8 @@ type real_predicate =
| Fcmp_une
| Fcmp_true
exception IoError of string
(*===-- Modules -----------------------------------------------------------===*)
@ -1235,13 +1242,30 @@ external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
(*===-- Module providers --------------------------------------------------===*)
(** [create_module_provider m] encapsulates [m] in a module provider and takes
ownership of the module. See the constructor
[llvm::ExistingModuleProvider::ExistingModuleProvider]. **)
external create_module_provider : llmodule -> llmoduleprovider
= "LLVMCreateModuleProviderForExistingModule"
module ModuleProvider : sig
(** [create_module_provider m] encapsulates [m] in a module provider and takes
ownership of the module. See the constructor
[llvm::ExistingModuleProvider::ExistingModuleProvider]. **)
external create : llmodule -> llmoduleprovider
= "LLVMCreateModuleProviderForExistingModule"
(** [dispose_module_provider mp] destroys the module provider [mp] as well as
the contained module. **)
external dispose_module_provider : llmoduleprovider -> unit
= "llvm_dispose_module_provider"
(** [dispose_module_provider mp] destroys the module provider [mp] as well as
the contained module. **)
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
end
(*===-- Memory buffers ----------------------------------------------------===*)
module MemoryBuffer : sig
(** [of_file p] is the memory buffer containing the contents of the file at
path [p]. If the file could not be read, then [IoError msg] is raised. **)
external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file"
(** [stdin ()] is the memory buffer containing the contents of standard input.
If standard input is empty, then [IoError msg] is raised. **)
external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin"
(** Disposes of a memory buffer. **)
external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
end

View File

@ -20,8 +20,33 @@
#include "caml/custom.h"
#include "caml/mlvalues.h"
#include "caml/memory.h"
#include "caml/fail.h"
#include "caml/callback.h"
#include "llvm/Config/config.h"
#include <assert.h>
#include <stdlib.h>
/* Can't use the recommended caml_named_value mechanism for backwards
compatibility reasons. This is largely equivalent. */
static value llvm_ioerror_exn;
CAMLprim value llvm_register_core_exns(value IoError) {
llvm_ioerror_exn = Field(IoError, 0);
register_global_root(&llvm_ioerror_exn);
return Val_unit;
}
void llvm_raise(value Prototype, char *Message) {
CAMLparam1(Prototype);
CAMLlocal1(CamlMessage);
CamlMessage = copy_string(Message);
LLVMDisposeMessage(Message);
raise_with_arg(Prototype, CamlMessage);
CAMLnoreturn;
}
/*===-- Modules -----------------------------------------------------------===*/
@ -1071,3 +1096,39 @@ CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) {
LLVMDisposeModuleProvider(MP);
return Val_unit;
}
/*===-- Memory buffers ----------------------------------------------------===*/
/* string -> llmemorybuffer
raises IoError msg on error */
CAMLprim value llvm_memorybuffer_of_file(value Path) {
CAMLparam1(Path);
char *Message;
LLVMMemoryBufferRef MemBuf;
if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
&MemBuf, &Message))
llvm_raise(llvm_ioerror_exn, Message);
CAMLreturn((value) MemBuf);
}
/* unit -> llmemorybuffer
raises IoError msg on error */
CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
char *Message;
LLVMMemoryBufferRef MemBuf;
if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
llvm_raise(llvm_ioerror_exn, Message);
return MemBuf;
}
/* llmemorybuffer -> unit */
CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
LLVMDisposeMemoryBuffer(MemBuf);
return Val_unit;
}

View File

@ -34,13 +34,11 @@ typedef enum {
/* Verifies that a module is valid, taking the specified action if not.
Optionally returns a human-readable description of any invalid constructs. */
Optionally returns a human-readable description of any invalid constructs.
OutMessage must be disposed with LLVMDisposeMessage. */
int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
char **OutMessage);
/* Disposes of the message allocated by the verifier, if any. */
void LLVMDisposeVerifierMessage(char *Message);
/* Verifies that a single function is valid, taking the specified action. Useful
for debugging. */
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);

View File

@ -26,21 +26,18 @@ extern "C" {
#endif
/* Reads a module from the specified path, returning a reference to the module
via the OutModule parameter. Returns 0 on success. Optionally returns a
human-readable error message. */
int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
char **OutMessage);
/* Builds a module from the bitcode in the specified memory buffer, returning a
reference to the module via the OutModule parameter. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage);
/* Reads a module from the specified path, returning a reference to a lazy
module provider via the OutModule parameter. Returns 0 on success. Optionally
returns a human-readable error message. */
int LLVMCreateModuleProviderFromFile(const char *Path,
LLVMModuleProviderRef *OutMP,
char **OutMessage);
/* Disposes of the message allocated by the bitcode reader, if any. */
void LLVMDisposeBitcodeReaderMessage(char *Message);
/* Reads a module from the specified path, returning via the OutMP parameter
a module provider which performs lazy deserialization. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage);
#ifdef __cplusplus

View File

@ -51,8 +51,17 @@ typedef struct LLVMOpaqueTypeHandle *LLVMTypeHandleRef;
typedef struct LLVMOpaqueValue *LLVMValueRef;
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
/* Used to provide a module to JIT or interpreter.
* See the llvm::ModuleProvider class.
*/
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
/* Used to provide a module to JIT or interpreter.
* See the llvm::MemoryBuffer class.
*/
typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
typedef enum {
LLVMVoidTypeKind, /* type with no size */
LLVMFloatTypeKind, /* 32 bit floating point type */
@ -129,6 +138,11 @@ typedef enum {
} LLVMRealPredicate;
/*===-- Error handling ----------------------------------------------------===*/
void LLVMDisposeMessage(char *Message);
/*===-- Modules -----------------------------------------------------------===*/
/* Create and destroy modules. */
@ -491,6 +505,7 @@ LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
LLVMValueRef V2, LLVMValueRef Mask,
const char *Name);
/*===-- Module providers --------------------------------------------------===*/
/* Encapsulates the module M in a module provider, taking ownership of the
@ -505,28 +520,45 @@ LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
*/
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
/*===-- Memory buffers ----------------------------------------------------===*/
int LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
#ifdef __cplusplus
}
namespace llvm {
class ModuleProvider;
class MemoryBuffer;
/* Opaque module conversions
*/
inline Module *unwrap(LLVMModuleRef M) {
return reinterpret_cast<Module*>(M);
}
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
inline ty *unwrap(ref P) { \
return reinterpret_cast<ty*>(P); \
} \
\
inline ref wrap(const ty *P) { \
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
}
inline LLVMModuleRef wrap(Module *M) {
return reinterpret_cast<LLVMModuleRef>(M);
}
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Type, LLVMTypeRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Value, LLVMValueRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMBuilder, LLVMBuilderRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ModuleProvider, LLVMModuleProviderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
/* Opaque type conversions
*/
inline Type *unwrap(LLVMTypeRef Ty) {
return reinterpret_cast<Type*>(Ty);
}
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
/* Specialized opaque type conversions.
*/
template<typename T>
inline T *unwrap(LLVMTypeRef Ty) {
return cast<T>(unwrap(Ty));
@ -536,20 +568,12 @@ namespace llvm {
return reinterpret_cast<Type**>(Tys);
}
inline LLVMTypeRef wrap(const Type *Ty) {
return reinterpret_cast<LLVMTypeRef>(const_cast<Type*>(Ty));
}
inline LLVMTypeRef *wrap(const Type **Tys) {
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
}
/* Opaque value conversions
/* Specialized opaque value conversions.
*/
inline Value *unwrap(LLVMValueRef Val) {
return reinterpret_cast<Value*>(Val);
}
template<typename T>
inline T *unwrap(LLVMValueRef Val) {
return cast<T>(unwrap(Val));
@ -568,53 +592,9 @@ namespace llvm {
return reinterpret_cast<T**>(Vals);
}
inline LLVMValueRef wrap(const Value *Val) {
return reinterpret_cast<LLVMValueRef>(const_cast<Value*>(Val));
}
inline LLVMValueRef *wrap(const Value **Vals) {
return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
}
/* Basic block conversions
*/
inline BasicBlock *unwrap(LLVMBasicBlockRef BBRef) {
return reinterpret_cast<BasicBlock*>(BBRef);
}
inline LLVMBasicBlockRef wrap(const BasicBlock *BB) {
return reinterpret_cast<LLVMBasicBlockRef>(const_cast<BasicBlock*>(BB));
}
/* Opaque builder conversions.
*/
inline LLVMBuilder *unwrap(LLVMBuilderRef B) {
return reinterpret_cast<LLVMBuilder*>(B);
}
inline LLVMBuilderRef wrap(LLVMBuilder *B) {
return reinterpret_cast<LLVMBuilderRef>(B);
}
/* Opaque type handle conversions.
*/
inline PATypeHolder *unwrap(LLVMTypeHandleRef B) {
return reinterpret_cast<PATypeHolder*>(B);
}
inline LLVMTypeHandleRef wrap(PATypeHolder *B) {
return reinterpret_cast<LLVMTypeHandleRef>(B);
}
/* Opaque module provider conversions.
*/
inline ModuleProvider *unwrap(LLVMModuleProviderRef P) {
return reinterpret_cast<ModuleProvider*>(P);
}
inline LLVMModuleProviderRef wrap(ModuleProvider *P) {
return reinterpret_cast<LLVMModuleProviderRef>(P);
}
}
#endif /* !defined(__cplusplus) */

View File

@ -27,10 +27,6 @@ int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
return Result;
}
void LLVMDisposeVerifierMessage(char *Message) {
free(Message);
}
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) {
return verifyFunction(*unwrap<Function>(Fn),
static_cast<VerifierFailureAction>(Action));

View File

@ -14,19 +14,14 @@
using namespace llvm;
int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
char **OutMessage) {
/* Builds a module from the bitcode in the specified memory buffer, returning a
reference to the module via the OutModule parameter. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage) {
std::string Message;
MemoryBuffer *buf = MemoryBuffer::getFile(Path, strlen(Path), &Message);
if (!buf) {
if (!OutMessage)
*OutMessage = strdup(Message.c_str());
return 1;
}
*OutModule = wrap(ParseBitcodeFile(buf, &Message));
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), &Message));
if (!*OutModule) {
if (OutMessage)
*OutMessage = strdup(Message.c_str());
@ -36,7 +31,20 @@ int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
return 0;
}
void LLVMDisposeBitcodeReaderMessage(char *Message) {
if (Message)
free(Message);
/* Reads a module from the specified path, returning via the OutModule parameter
a module provider which performs lazy deserialization. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage) {
std::string Message;
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), &Message));
if (!*OutMP) {
if (OutMessage)
*OutMessage = strdup(Message.c_str());
return 1;
}
return 0;
}

View File

@ -19,11 +19,20 @@
#include "llvm/GlobalVariable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cassert>
#include <cstdlib>
using namespace llvm;
/*===-- Error handling ----------------------------------------------------===*/
void LLVMDisposeMessage(char *Message) {
free(Message);
}
/*===-- Operations on modules ---------------------------------------------===*/
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) {
@ -1048,3 +1057,33 @@ void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) {
delete unwrap(MP);
}
/*===-- Memory buffers ----------------------------------------------------===*/
int LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage) {
std::string Error;
if (MemoryBuffer *MB = MemoryBuffer::getFile(Path, strlen(Path), &Error)) {
*OutMemBuf = wrap(MB);
return 0;
}
*OutMessage = strdup(Error.c_str());
return 1;
}
int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage) {
if (MemoryBuffer *MB = MemoryBuffer::getSTDIN()) {
*OutMemBuf = wrap(MB);
return 0;
}
*OutMessage = strdup("stdin is empty.");
return 1;
}
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) {
delete unwrap(MemBuf);
}

View File

@ -18,6 +18,58 @@ let _ =
Llvm.dispose_module m;
test (match Llvm_bitreader.read_bitcode_file fn with
| Llvm_bitreader.Bitreader_success m -> Llvm.dispose_module m; true
| Llvm_bitreader.Bitreader_failure _ -> false)
(* parse_bitcode *)
begin
let mb = Llvm.MemoryBuffer.of_file fn in
begin try
let m = Llvm_bitreader.parse_bitcode mb in
Llvm.dispose_module m
with x ->
Llvm.MemoryBuffer.dispose;
raise x
end
end;
(* MemoryBuffer.of_file *)
test begin try
let mb = Llvm.MemoryBuffer.of_file (fn ^ ".bogus") in
Llvm.MemoryBuffer.dispose mb;
false
with Llvm.IoError _ ->
true
end;
(* get_module_provider *)
begin
let mb = Llvm.MemoryBuffer.of_file fn in
let mp = begin try
Llvm_bitreader.get_module_provider mb
with x ->
Llvm.MemoryBuffer.dispose mb;
raise x
end in
Llvm.ModuleProvider.dispose mp
end;
(* corrupt the bitcode *)
let fn = fn ^ ".txt" in
begin let oc = open_out fn in
output_string oc "not a bitcode file\n";
close_out oc
end;
(* test get_module_provider exceptions *)
test begin
try
let mb = Llvm.MemoryBuffer.of_file fn in
let mp = begin try
Llvm_bitreader.get_module_provider mb
with x ->
Llvm.MemoryBuffer.dispose mb;
raise x
end in
Llvm.ModuleProvider.dispose mp;
false
with Llvm_bitreader.Error _ ->
true
end

View File

@ -805,8 +805,8 @@ let test_builder () =
let test_module_provider () =
let m = create_module "test" in
let mp = create_module_provider m in
dispose_module_provider mp
let mp = ModuleProvider.create m in
ModuleProvider.dispose mp
(*===-- Writer ------------------------------------------------------------===*)