mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
Adding bindings for memory buffers and module providers. Switching
to exceptions rather than variants for error handling in Ocaml. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -98,6 +98,7 @@
|
|||||||
9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitcodeWriterPass.cpp; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
9F7793480C73BC2000551F9C /* GVNPRE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GVNPRE.cpp; sourceTree = "<group>"; };
|
||||||
@ -1241,6 +1242,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9F7C2C4F0CB9496C00498408 /* analysis.ml */,
|
9F7C2C4F0CB9496C00498408 /* analysis.ml */,
|
||||||
|
9F6B2CC00D0F6E56000F00FD /* bitreader.ml */,
|
||||||
9F7C2C520CB9496C00498408 /* bitwriter.ml */,
|
9F7C2C520CB9496C00498408 /* bitwriter.ml */,
|
||||||
9F7C2C5D0CB9496C00498408 /* vmcore.ml */,
|
9F7C2C5D0CB9496C00498408 /* vmcore.ml */,
|
||||||
);
|
);
|
||||||
|
@ -37,7 +37,7 @@ CAMLprim value llvm_verify_module(LLVMModuleRef M) {
|
|||||||
Store_field(Option, 0, String);
|
Store_field(Option, 0, String);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMDisposeVerifierMessage(Message);
|
LLVMDisposeMessage(Message);
|
||||||
|
|
||||||
CAMLreturn(Option);
|
CAMLreturn(Option);
|
||||||
}
|
}
|
||||||
|
@ -16,31 +16,46 @@
|
|||||||
#include "caml/alloc.h"
|
#include "caml/alloc.h"
|
||||||
#include "caml/mlvalues.h"
|
#include "caml/mlvalues.h"
|
||||||
#include "caml/memory.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 -----------------------------------------------------------===*/
|
/*===-- Modules -----------------------------------------------------------===*/
|
||||||
|
|
||||||
/* string -> bitreader_result
|
/* Llvm.llmemorybuffer -> Llvm.module */
|
||||||
|
CAMLprim value llvm_get_module_provider(LLVMMemoryBufferRef MemBuf) {
|
||||||
|
CAMLparam0();
|
||||||
|
CAMLlocal2(Variant, MessageVal);
|
||||||
|
char *Message;
|
||||||
|
|
||||||
type bitreader_result =
|
LLVMModuleProviderRef MP;
|
||||||
| Bitreader_success of Llvm.llmodule
|
if (LLVMGetBitcodeModuleProvider(MemBuf, &MP, &Message))
|
||||||
| Bitreader_failure of string
|
llvm_raise(llvm_bitreader_error_exn, Message);
|
||||||
*/
|
|
||||||
CAMLprim value llvm_read_bitcode_file(value Path) {
|
CAMLreturn((value) MemBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||||
|
CAMLprim value llvm_parse_bitcode(LLVMMemoryBufferRef MemBuf) {
|
||||||
|
CAMLparam0();
|
||||||
|
CAMLlocal2(Variant, MessageVal);
|
||||||
LLVMModuleRef M;
|
LLVMModuleRef M;
|
||||||
char *Message;
|
char *Message;
|
||||||
CAMLparam1(Path);
|
|
||||||
CAMLlocal2(Variant, MessageVal);
|
|
||||||
|
|
||||||
if (LLVMReadBitcodeFromFile(String_val(Path), &M, &Message)) {
|
if (LLVMParseBitcode(MemBuf, &M, &Message))
|
||||||
MessageVal = copy_string(Message);
|
llvm_raise(llvm_bitreader_error_exn, Message);
|
||||||
LLVMDisposeBitcodeReaderMessage(Message);
|
|
||||||
|
|
||||||
Variant = alloc(1, 1);
|
CAMLreturn((value) M);
|
||||||
Field(Variant, 0) = MessageVal;
|
|
||||||
} else {
|
|
||||||
Variant = alloc(1, 0);
|
|
||||||
Field(Variant, 0) = Val_op(M);
|
|
||||||
}
|
|
||||||
|
|
||||||
CAMLreturn(Variant);
|
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
*===----------------------------------------------------------------------===*)
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
|
||||||
type bitreader_result =
|
exception Error of string
|
||||||
| Bitreader_success of Llvm.llmodule
|
|
||||||
| Bitreader_failure of string
|
|
||||||
|
|
||||||
|
external register_exns : exn -> unit = "llvm_register_bitreader_exns"
|
||||||
|
let _ = register_exns (Error "")
|
||||||
|
|
||||||
external read_bitcode_file : string -> bitreader_result
|
external get_module_provider : Llvm.llmemorybuffer -> Llvm.llmoduleprovider
|
||||||
= "llvm_read_bitcode_file"
|
= "llvm_get_module_provider"
|
||||||
|
external parse_bitcode : Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_parse_bitcode"
|
||||||
|
@ -13,13 +13,18 @@
|
|||||||
*===----------------------------------------------------------------------===*)
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
|
||||||
type bitreader_result =
|
exception Error of string
|
||||||
| Bitreader_success of Llvm.llmodule
|
|
||||||
| Bitreader_failure 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
|
(** [parse_bitcode mb] parses the bitcode for a new module [m] from the memory
|
||||||
[path]. Returns [Reader_success m] if successful, and [Reader_failure msg]
|
buffer [mb]. Returns [Success m] if successful, and [Failure msg] otherwise,
|
||||||
otherwise, where [msg] is a description of the error encountered. **)
|
where [msg] is a description of the error encountered.
|
||||||
external read_bitcode_file : string -> bitreader_result
|
See the function [llvm::ParseBitcodeFile]. **)
|
||||||
= "llvm_read_bitcode_file"
|
external parse_bitcode : Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_parse_bitcode"
|
||||||
|
@ -15,6 +15,7 @@ type llvalue
|
|||||||
type llbasicblock
|
type llbasicblock
|
||||||
type llbuilder
|
type llbuilder
|
||||||
type llmoduleprovider
|
type llmoduleprovider
|
||||||
|
type llmemorybuffer
|
||||||
|
|
||||||
type type_kind =
|
type type_kind =
|
||||||
Void_type
|
Void_type
|
||||||
@ -84,6 +85,11 @@ type real_predicate =
|
|||||||
| Fcmp_une
|
| Fcmp_une
|
||||||
| Fcmp_true
|
| Fcmp_true
|
||||||
|
|
||||||
|
exception IoError of string
|
||||||
|
|
||||||
|
external register_exns : exn -> unit = "llvm_register_core_exns"
|
||||||
|
let _ = register_exns (IoError "")
|
||||||
|
|
||||||
|
|
||||||
(*===-- Modules -----------------------------------------------------------===*)
|
(*===-- Modules -----------------------------------------------------------===*)
|
||||||
|
|
||||||
@ -432,10 +438,21 @@ external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
|
|||||||
|
|
||||||
|
|
||||||
(*===-- Module providers --------------------------------------------------===*)
|
(*===-- Module providers --------------------------------------------------===*)
|
||||||
external create_module_provider : llmodule -> llmoduleprovider
|
|
||||||
= "LLVMCreateModuleProviderForExistingModule"
|
module ModuleProvider = struct
|
||||||
external dispose_module_provider : llmoduleprovider -> unit
|
external create : llmodule -> llmoduleprovider
|
||||||
= "llvm_dispose_module_provider"
|
= "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 -------------------------------------------------------===*)
|
(*===-- Non-Externs -------------------------------------------------------===*)
|
||||||
|
@ -40,9 +40,14 @@ type llbasicblock
|
|||||||
class. **)
|
class. **)
|
||||||
type llbuilder
|
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
|
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
|
(** The kind of an [lltype], the result of [classify_type ty]. See the
|
||||||
[llvm::Type::TypeID] enumeration. **)
|
[llvm::Type::TypeID] enumeration. **)
|
||||||
type type_kind =
|
type type_kind =
|
||||||
@ -129,6 +134,8 @@ type real_predicate =
|
|||||||
| Fcmp_une
|
| Fcmp_une
|
||||||
| Fcmp_true
|
| Fcmp_true
|
||||||
|
|
||||||
|
exception IoError of string
|
||||||
|
|
||||||
|
|
||||||
(*===-- Modules -----------------------------------------------------------===*)
|
(*===-- Modules -----------------------------------------------------------===*)
|
||||||
|
|
||||||
@ -1235,13 +1242,30 @@ external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
|
|||||||
|
|
||||||
(*===-- Module providers --------------------------------------------------===*)
|
(*===-- Module providers --------------------------------------------------===*)
|
||||||
|
|
||||||
(** [create_module_provider m] encapsulates [m] in a module provider and takes
|
module ModuleProvider : sig
|
||||||
ownership of the module. See the constructor
|
(** [create_module_provider m] encapsulates [m] in a module provider and takes
|
||||||
[llvm::ExistingModuleProvider::ExistingModuleProvider]. **)
|
ownership of the module. See the constructor
|
||||||
external create_module_provider : llmodule -> llmoduleprovider
|
[llvm::ExistingModuleProvider::ExistingModuleProvider]. **)
|
||||||
= "LLVMCreateModuleProviderForExistingModule"
|
external create : llmodule -> llmoduleprovider
|
||||||
|
= "LLVMCreateModuleProviderForExistingModule"
|
||||||
|
|
||||||
(** [dispose_module_provider mp] destroys the module provider [mp] as well as
|
(** [dispose_module_provider mp] destroys the module provider [mp] as well as
|
||||||
the contained module. **)
|
the contained module. **)
|
||||||
external dispose_module_provider : llmoduleprovider -> unit
|
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
|
||||||
= "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/custom.h"
|
||||||
#include "caml/mlvalues.h"
|
#include "caml/mlvalues.h"
|
||||||
#include "caml/memory.h"
|
#include "caml/memory.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/callback.h"
|
||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
#include <assert.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 -----------------------------------------------------------===*/
|
/*===-- Modules -----------------------------------------------------------===*/
|
||||||
@ -1071,3 +1096,39 @@ CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) {
|
|||||||
LLVMDisposeModuleProvider(MP);
|
LLVMDisposeModuleProvider(MP);
|
||||||
return Val_unit;
|
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.
|
/* 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,
|
int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||||
char **OutMessage);
|
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
|
/* Verifies that a single function is valid, taking the specified action. Useful
|
||||||
for debugging. */
|
for debugging. */
|
||||||
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
|
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
|
||||||
|
@ -26,21 +26,18 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Reads a module from the specified path, returning a reference to the module
|
/* Builds a module from the bitcode in the specified memory buffer, returning a
|
||||||
via the OutModule parameter. Returns 0 on success. Optionally returns a
|
reference to the module via the OutModule parameter. Returns 0 on success.
|
||||||
human-readable error message. */
|
Optionally returns a human-readable error message via OutMessage. */
|
||||||
int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
|
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||||
char **OutMessage);
|
LLVMModuleRef *OutModule, char **OutMessage);
|
||||||
|
|
||||||
/* Reads a module from the specified path, returning a reference to a lazy
|
/* Reads a module from the specified path, returning via the OutMP parameter
|
||||||
module provider via the OutModule parameter. Returns 0 on success. Optionally
|
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||||
returns a human-readable error message. */
|
Optionally returns a human-readable error message via OutMessage. */
|
||||||
int LLVMCreateModuleProviderFromFile(const char *Path,
|
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||||
LLVMModuleProviderRef *OutMP,
|
LLVMModuleProviderRef *OutMP,
|
||||||
char **OutMessage);
|
char **OutMessage);
|
||||||
|
|
||||||
/* Disposes of the message allocated by the bitcode reader, if any. */
|
|
||||||
void LLVMDisposeBitcodeReaderMessage(char *Message);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -51,8 +51,17 @@ typedef struct LLVMOpaqueTypeHandle *LLVMTypeHandleRef;
|
|||||||
typedef struct LLVMOpaqueValue *LLVMValueRef;
|
typedef struct LLVMOpaqueValue *LLVMValueRef;
|
||||||
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
||||||
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
|
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
|
||||||
|
|
||||||
|
/* Used to provide a module to JIT or interpreter.
|
||||||
|
* See the llvm::ModuleProvider class.
|
||||||
|
*/
|
||||||
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
|
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
|
||||||
|
|
||||||
|
/* Used to provide a module to JIT or interpreter.
|
||||||
|
* See the llvm::MemoryBuffer class.
|
||||||
|
*/
|
||||||
|
typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LLVMVoidTypeKind, /* type with no size */
|
LLVMVoidTypeKind, /* type with no size */
|
||||||
LLVMFloatTypeKind, /* 32 bit floating point type */
|
LLVMFloatTypeKind, /* 32 bit floating point type */
|
||||||
@ -129,6 +138,11 @@ typedef enum {
|
|||||||
} LLVMRealPredicate;
|
} LLVMRealPredicate;
|
||||||
|
|
||||||
|
|
||||||
|
/*===-- Error handling ----------------------------------------------------===*/
|
||||||
|
|
||||||
|
void LLVMDisposeMessage(char *Message);
|
||||||
|
|
||||||
|
|
||||||
/*===-- Modules -----------------------------------------------------------===*/
|
/*===-- Modules -----------------------------------------------------------===*/
|
||||||
|
|
||||||
/* Create and destroy modules. */
|
/* Create and destroy modules. */
|
||||||
@ -491,6 +505,7 @@ LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
|
|||||||
LLVMValueRef V2, LLVMValueRef Mask,
|
LLVMValueRef V2, LLVMValueRef Mask,
|
||||||
const char *Name);
|
const char *Name);
|
||||||
|
|
||||||
|
|
||||||
/*===-- Module providers --------------------------------------------------===*/
|
/*===-- Module providers --------------------------------------------------===*/
|
||||||
|
|
||||||
/* Encapsulates the module M in a module provider, taking ownership of the
|
/* Encapsulates the module M in a module provider, taking ownership of the
|
||||||
@ -505,28 +520,45 @@ LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
|
|||||||
*/
|
*/
|
||||||
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class ModuleProvider;
|
class ModuleProvider;
|
||||||
|
class MemoryBuffer;
|
||||||
|
|
||||||
/* Opaque module conversions
|
#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)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
|
||||||
|
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
|
||||||
|
|
||||||
|
/* Specialized opaque type conversions.
|
||||||
*/
|
*/
|
||||||
inline Module *unwrap(LLVMModuleRef M) {
|
|
||||||
return reinterpret_cast<Module*>(M);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LLVMModuleRef wrap(Module *M) {
|
|
||||||
return reinterpret_cast<LLVMModuleRef>(M);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Opaque type conversions
|
|
||||||
*/
|
|
||||||
inline Type *unwrap(LLVMTypeRef Ty) {
|
|
||||||
return reinterpret_cast<Type*>(Ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T *unwrap(LLVMTypeRef Ty) {
|
inline T *unwrap(LLVMTypeRef Ty) {
|
||||||
return cast<T>(unwrap(Ty));
|
return cast<T>(unwrap(Ty));
|
||||||
@ -536,20 +568,12 @@ namespace llvm {
|
|||||||
return reinterpret_cast<Type**>(Tys);
|
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) {
|
inline LLVMTypeRef *wrap(const Type **Tys) {
|
||||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<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>
|
template<typename T>
|
||||||
inline T *unwrap(LLVMValueRef Val) {
|
inline T *unwrap(LLVMValueRef Val) {
|
||||||
return cast<T>(unwrap(Val));
|
return cast<T>(unwrap(Val));
|
||||||
@ -568,53 +592,9 @@ namespace llvm {
|
|||||||
return reinterpret_cast<T**>(Vals);
|
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) {
|
inline LLVMValueRef *wrap(const Value **Vals) {
|
||||||
return reinterpret_cast<LLVMValueRef*>(const_cast<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) */
|
#endif /* !defined(__cplusplus) */
|
||||||
|
@ -27,10 +27,6 @@ int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMDisposeVerifierMessage(char *Message) {
|
|
||||||
free(Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) {
|
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) {
|
||||||
return verifyFunction(*unwrap<Function>(Fn),
|
return verifyFunction(*unwrap<Function>(Fn),
|
||||||
static_cast<VerifierFailureAction>(Action));
|
static_cast<VerifierFailureAction>(Action));
|
||||||
|
@ -14,19 +14,14 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
/* Builds a module from the bitcode in the specified memory buffer, returning a
|
||||||
int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
|
reference to the module via the OutModule parameter. Returns 0 on success.
|
||||||
char **OutMessage) {
|
Optionally returns a human-readable error message via OutMessage. */
|
||||||
|
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||||
|
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||||
std::string Message;
|
std::string Message;
|
||||||
|
|
||||||
MemoryBuffer *buf = MemoryBuffer::getFile(Path, strlen(Path), &Message);
|
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), &Message));
|
||||||
if (!buf) {
|
|
||||||
if (!OutMessage)
|
|
||||||
*OutMessage = strdup(Message.c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*OutModule = wrap(ParseBitcodeFile(buf, &Message));
|
|
||||||
if (!*OutModule) {
|
if (!*OutModule) {
|
||||||
if (OutMessage)
|
if (OutMessage)
|
||||||
*OutMessage = strdup(Message.c_str());
|
*OutMessage = strdup(Message.c_str());
|
||||||
@ -36,7 +31,20 @@ int LLVMReadBitcodeFromFile(const char *Path, LLVMModuleRef *OutModule,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMDisposeBitcodeReaderMessage(char *Message) {
|
/* Reads a module from the specified path, returning via the OutModule parameter
|
||||||
if (Message)
|
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||||
free(Message);
|
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/GlobalVariable.h"
|
||||||
#include "llvm/TypeSymbolTable.h"
|
#include "llvm/TypeSymbolTable.h"
|
||||||
#include "llvm/ModuleProvider.h"
|
#include "llvm/ModuleProvider.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
|
||||||
|
/*===-- Error handling ----------------------------------------------------===*/
|
||||||
|
|
||||||
|
void LLVMDisposeMessage(char *Message) {
|
||||||
|
free(Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*===-- Operations on modules ---------------------------------------------===*/
|
/*===-- Operations on modules ---------------------------------------------===*/
|
||||||
|
|
||||||
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) {
|
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) {
|
||||||
@ -1048,3 +1057,33 @@ void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) {
|
|||||||
delete unwrap(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;
|
Llvm.dispose_module m;
|
||||||
|
|
||||||
test (match Llvm_bitreader.read_bitcode_file fn with
|
(* parse_bitcode *)
|
||||||
| Llvm_bitreader.Bitreader_success m -> Llvm.dispose_module m; true
|
begin
|
||||||
| Llvm_bitreader.Bitreader_failure _ -> false)
|
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 test_module_provider () =
|
||||||
let m = create_module "test" in
|
let m = create_module "test" in
|
||||||
let mp = create_module_provider m in
|
let mp = ModuleProvider.create m in
|
||||||
dispose_module_provider mp
|
ModuleProvider.dispose mp
|
||||||
|
|
||||||
|
|
||||||
(*===-- Writer ------------------------------------------------------------===*)
|
(*===-- Writer ------------------------------------------------------------===*)
|
||||||
|
Reference in New Issue
Block a user