diff options
author | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-12-19 22:30:40 +0000 |
---|---|---|
committer | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-12-19 22:30:40 +0000 |
commit | 91ab68bbf0e71ea233d92871f637fc48b6c4db8d (patch) | |
tree | 6bfc10578fca9bc86214295b290bec5b0821be8f /bindings | |
parent | 15e8f535219301e37eceba56d3ae047db8e10f4f (diff) | |
download | external_llvm-91ab68bbf0e71ea233d92871f637fc48b6c4db8d.zip external_llvm-91ab68bbf0e71ea233d92871f637fc48b6c4db8d.tar.gz external_llvm-91ab68bbf0e71ea233d92871f637fc48b6c4db8d.tar.bz2 |
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
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/ocaml/analysis/analysis_ocaml.c | 2 | ||||
-rw-r--r-- | bindings/ocaml/bitreader/bitreader_ocaml.c | 53 | ||||
-rw-r--r-- | bindings/ocaml/bitreader/llvm_bitreader.ml | 12 | ||||
-rw-r--r-- | bindings/ocaml/bitreader/llvm_bitreader.mli | 21 | ||||
-rw-r--r-- | bindings/ocaml/llvm/llvm.ml | 25 | ||||
-rw-r--r-- | bindings/ocaml/llvm/llvm.mli | 46 | ||||
-rw-r--r-- | bindings/ocaml/llvm/llvm_ocaml.c | 61 |
7 files changed, 172 insertions, 48 deletions
diff --git a/bindings/ocaml/analysis/analysis_ocaml.c b/bindings/ocaml/analysis/analysis_ocaml.c index c77fa73..9286b4c 100644 --- a/bindings/ocaml/analysis/analysis_ocaml.c +++ b/bindings/ocaml/analysis/analysis_ocaml.c @@ -37,7 +37,7 @@ CAMLprim value llvm_verify_module(LLVMModuleRef M) { Store_field(Option, 0, String); } - LLVMDisposeVerifierMessage(Message); + LLVMDisposeMessage(Message); CAMLreturn(Option); } diff --git a/bindings/ocaml/bitreader/bitreader_ocaml.c b/bindings/ocaml/bitreader/bitreader_ocaml.c index 7088fa5..87477f6 100644 --- a/bindings/ocaml/bitreader/bitreader_ocaml.c +++ b/bindings/ocaml/bitreader/bitreader_ocaml.c @@ -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); } diff --git a/bindings/ocaml/bitreader/llvm_bitreader.ml b/bindings/ocaml/bitreader/llvm_bitreader.ml index 39d0434..266ff15 100644 --- a/bindings/ocaml/bitreader/llvm_bitreader.ml +++ b/bindings/ocaml/bitreader/llvm_bitreader.ml @@ -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" diff --git a/bindings/ocaml/bitreader/llvm_bitreader.mli b/bindings/ocaml/bitreader/llvm_bitreader.mli index 37750bc..bc5efc8 100644 --- a/bindings/ocaml/bitreader/llvm_bitreader.mli +++ b/bindings/ocaml/bitreader/llvm_bitreader.mli @@ -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" diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index 5a5f4e7..58d9d50 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -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 -------------------------------------------------------===*) diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 4646c57..546ab45 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -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" - -(** [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" +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 : 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 diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 43b6167..5cd9526 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -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; +} + |