forked from OSchip/llvm-project
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:
parent
9a53275918
commit
34eb6d877e
|
@ -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 */,
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ CAMLprim value llvm_verify_module(LLVMModuleRef M) {
|
|||
Store_field(Option, 0, String);
|
||||
}
|
||||
|
||||
LLVMDisposeVerifierMessage(Message);
|
||||
LLVMDisposeMessage(Message);
|
||||
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 -------------------------------------------------------===*)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ------------------------------------------------------------===*)
|
||||
|
|
Loading…
Reference in New Issue